Hi all,
Why is NIM net module closing an UDP socket the moment "send" method ends?
This is the code I use:
#? braces
import net
# proc udpSocket(): Socket {
# result = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, true);
# }
proc hello() {
var socket = dial("127.0.0.1", Port(6000), IPPROTO_UDP);
socket.setSockOpt(OptKeepAlive, true);
socket.send("(init MyTeam (version 9))");
#socket.send("(move 0 0)");
while true {
var data: string;
data = socket.recvLine();
echo data;
}
}
when (isMainModule){
hello();
}
I have tried the same thing with a Java UDP socket and that one works. The socket is kept connected until I close it https://systembash.com/a-simple-java-udp-server-and-udp-client/
Thanks.
Thanks for the help, but that is not the issue.
There is a UDP server running and listening on port 6000. That is why the java client works. The Nim client works as well but just for the first message. After that the server console tells me that the client has disconnected. The connection is closed after the send command.
For UDP, you don't send / recv but sendTo / recvFrom.
See this stackoverflow answer for detailed answer.
For simple UDP server/client in Nim. Here's the example:
server.nim
import net
var server = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
server.bindAddr Port(3000)
echo "server bound to port 3000"
while true:
var
data = ""
address = ""
length = 64
port: Port
discard server.recvFrom(data, length, address, port)
echo address, " send ", data, " by ", $port
discard server.sendTo(address, port, "server echo back " & data)
client.nim
import net
var socket = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
for count in 1 ..< 5:
var mystatus = "I'm sending for " & $count & " times"
discard socket.sendTo("localhost", Port(3000), mystatus)
var
data = ""
address = ""
senderport: Port
length = 64
discard socket.recvFrom(data, length, address, senderport)
echo data
Observe that no need to listen and accept for the server.
Thanks, but still doesn't solve the issue.
I am trying to build a client library for the roboCUP 2D simulation server (rcssserver). You can find documentation here: https://sourceforge.net/projects/sserver/files/rcssmanual/9-20030211/
If I use any of the UDP implementations in NIM this is what I get on the server console:
$ rcssserver
rcssserver-15.2.2
Copyright (C) 1995, 1996, 1997, 1998, 1999 Electrotechnical Laboratory.
2000 - RoboCup Soccer Simulator Maintenance Group.
Simulator Random Seed: 1501244014
CSVSaver: Ready
STDOutSaver: Ready
Using simulator's random seed as Hetero Player Seed: 1501244014
wind factor: rand: 0.000000, vector: (0.000000, 0.000000)
Hit CTRL-C to exit
A new (v9) player (MyTeam 1) connected.
A player disconnected : (MyTeam 1)
If I use a simple JAVA UDP client implementation everything works as expected.
I will try the SDL2 UDP example and see if that works.
Thanks again.
@xyz32, could you show the revised version of your Nim UDP client? By definition, UDP is connection-less so it works that way.
Also, please show in what way it should work properly, because, like I said, UDP is connection-less.
@Arrrrrrrrr, https://systembash.com/a-simple-java-udp-server-and-udp-client/
@mashingan, I just created a new nim project and copy pasted your UDP client, and changed
mystatus = "I'm sending for " & $count & " times"
to read mystatus = "(init MyTeam (version 9))"
In the java example they only close the socket at the end of the example:
clientSocket.close();
Unless the socket was out of scope, it should (kinda) able to receive the message from server. The problem is server won't know whether its message received by client or not. So I cannot follow how UDP server knows the connection closed?
UDP, in simple term, only sends without caring whether the other end receives the message or not, whether the message is accurate or not, it works as if simple as a postman, he puts the letter in letterbox and doesn't care if letter will be read or not.
Also, you faithfully using Java implementation example of UDP client but in the end it just sends only one message before closing itself right? How do you know it works different with Nim UDP client?
@mashingan, I understand that the UDP protocol is fire and forget, but from what I know is built on top of a socket. For the java example I forgot to mention I put in a while (true) loop to keep it alive :). Sorry about that.
@Arrrrrrrrr, That is just me experimenting. The behaviour is the same with or without. For the windows server I don't know if they support it. Maybe a linux virtual machine and then
dnf install rcssserver-gui
.
Thanks.
Yeah, as @Arrrrrrrrr mentioned, no windows binary and I was too lazy to install libboost in my linux vm so I cannot experiment with rcss ;)
Anyway, I did some experiment with subscribing model using UDP, and I'm able to send the message to client repeatedly from server without client closing the connection.
the subsciber.nim is almost the same with example before
import net
var
socket = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
serverAddress = "localhost"
serverPort = Port(6000)
stdout.write "Insert initial message: "
var initmsg = stdin.readLine
discard socket.sendTo(serverAddress, serverPort, initmsg)
while true:
var
data = ""
address = ""
length = 1024
port: Port
discard socket.recvFrom(data, length, address, port)
echo data
close socket
In my case, the broadcaster always able to send to subscribing client (in real world, the connection wouldn't that reliable though). Also, no example of broadcaster.nim, that's too buggy and bad example of using spawn together with stdin , too embarrassed to show it ;)
In short, as long the socket isn't out of scope, it's there to listen any message its recvFrom
This code works, thank you. Doesn't seem to be too much different then the other one, but it works.
BTW Fedora labs have a "robotics lab" version that contains this server: https://labs.fedoraproject.org/
Cheers