On the off change that @dom96's advice to use async was part of the problem. I converted it to async: import asyncdispatch, asyncnet import std/[net, selectors, strformat, strutils] const cfgMaxPacket = 500 clientPort = 8800 clientHost = "127.0.0.1" serverPort = 9900 serverHost = "192.168.1.45" proc doit() {.async.} = let socket = newAsyncSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) events = newSelector[int]() socket.bindAddr(Port(clientPort), clientHost) events.registerHandle(socket.getFd, {Read}, 0) events.registerHandle(0, {Read}, 0) # stdin echo &"Listening to stdin and {clientHost}:{clientPort}; transmitting to {serverHost}:{serverPort}" while true: for got in events.select(-1): if got.fd == socket.getFd().int: var msgDetails = await socket.recvFrom(cfgMaxPacket) let message = msgDetails.data echo "got UDP: ", message.strip elif got.fd == 0: try: await socket.sendTo(serverHost, Port(serverPort), stdin.readLine()) except EOFError: quit() asyncCheck doit() runForever() Run
Sadly that does not fix it. Like before, a local address works for UDP, but everything else breaks.