bishboria

Receiving multiple UDP messages

TL;DR

Netcat stopped listening to incoming UDP messages being sent from an external program, so use

socat UDP-RECV:12345 STDOUT

instead of

nc -l -u 12345

More information

I've been using netcat to listen to UDP messages coming from a C program. The problem is that once a single message has been sent, netcat appears to stop processing further messages that are being sent.

A quick search came up with this stackoverflow answer:

When nc is listening to a UDP socket, it 'locks on' to the source port and source IP of the first packet it receives. Check out this trace:

socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(10000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
recvfrom(3, "f\n", 2048, MSG_PEEK, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, [16]) = 2
connect(3, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, 16) = 0

Here you can see that it created a UDP socket, set it for address reuse, and bound it to port 10,000. As soon as it received its first datagram (from port 52,832), it issued a connect system call 'connecting' it to the 127.0.0.1:52,832. For UDP, a connect rejects all packets that don't match the IP and port in the connect.

A comment on this answer recommends using socat instead:

Instead, I would recommend using socat. e.g. socat UDP-RECV:[port] STDOUT and socat STDIN UDP-DATAGRAM:[host]:[port]

The UDP-RECV:PORT address type option for socat allows multiple unspecified peers to send data. It also doesn't try to connect back to a peer, so the netcat issue doesn't happen.