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?

Reply via email to