I'm trying to set up a simple example for Socket programming and I've run into a confusing situation. I'm on Linux with 0.17.3 built from devel at some point today. Also tried on a different Linux machine with 0.17.2.
I set up a simple server for my socket read example.
#!/bin/sh
socat TCP4-LISTEN:5001,fork EXEC:"echo hi"
import net
var sock = newSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
sock.connect("127.0.0.1", Port(5001))
sock.send("Hello")
echo("Received: ")
echo(sock.recv(4000))
The call to recv hangs.
Watching with strace, the recvfrom syscall is called twice and hangs on the second call.
This can be traced to net.nim and a call to waitFor in recv.
I rewrote the example with asyncdispatch and got different behavior.
import asyncdispatch, asyncnet, net
proc test() {.async.} =
var sock = newAsyncSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
await sock.connect("127.0.0.1", Port(5001))
await sock.send("Hello")
echo("Received: ")
echo(await sock.recv(4000))
waitFor test()
A rough translation to Python behaves the same way as the async code snippet above and not the normal net-based code.
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
s.connect(("127.0.0.1", 5001))
s.send(b"Hello!")
print("Received: ")
print(s.recv(4000))
strace shows a very similar chain of syscalls without the repeated recvfrom.
Am I doing something wrong with the original Socket code?