Netcat – Behavior with Piping and UDP

netcatpipesocatudp

I guess this is close to linux – Netcat stops listening for UDP traffic – Super User, but I thought I'd better ask anyways

As far as versions of netcat I'm using Ubuntu 11.04 and the default netcat on it, which I'm guessing is the openbsd one:

$ nc
This is nc from the netcat-openbsd package. An alternative nc is available
in the netcat-traditional package.
usage: nc [-46DdhklnrStUuvzC] [-i interval] [-P proxy_username] [-p source_port]
      [-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_protocol]
      [-x proxy_address[:port]] [hostname] [port[s]]

 

This is what I find strange: the first case works as expected – I open a UDP server in one terminal:

$ sudo nc -ul 5000

… and in another terminal I initiate a new UDP client connection – and I type in hello three times, pressing ENTER after each:

$ nc -u 127.0.0.1 5000
hello
hello
hello
^C

… and going back to the server terminal, it has printed hello three times, as expected:

$ sudo nc -ul 5000 
hello
hello
hello
^C

 

So far so good, all works as expected. However, let's say I try now the same by piping input into the client; so establish first a UDP server in one terminal:

$ sudo nc -ul 5000

… and in another, pipe some data into nc as UDP client:

$ echo hello | nc -u 127.0.0.1 5000
hello
hello
^C

… after the client command, the shell sort of freezes as if waiting for input – so there I type hello and ENTER two more times; but the server has registered only the first hello (which was piped via echo). Furthermore, even if you press Ctrl-C, and try to repeat the client echo hello | nc -u 127.0.0.1 5000 command, the server will still remain on having reported just the very first hello:

$ sudo nc -ul 57130 
hello
^C

… and only after stopping the server with Ctrl-C and restarting it again, can one repeat the client echo hello | nc -u 127.0.0.1 5000 command and observe it working.

 

Is this the way nc is supposed to be behaving? I would expect that at least repeated calls to echo hello | nc -u 127.0.0.1 5000 would be registered – without having to restart the server? Or maybe there is a special command-line switch for that kind of behavior?

EDIT: I found this nice PDF presentation: socat – Handling all Kinds of Sockets, which contains the following netcat vs socat notes:

netcat – Limitations
● one-shot only (terminates after socket close)

Examples 1: netcat Replacement

● UDP client with source port:
nc -­u ­-p 500 1.2.3.4 500
socat ­- udp:1.2.3.4:500,sp=500
● TCP server:
nc ­-l ­-p 8080
socat ­- tcp­-l:8080,reuseaddr

… however, I'm pretty much getting the same behavior as above, if I replace the server command with "socat - udp4-listen:5000,reuseaddr" – and the client line with "socat - udp:127.0.0.1:5000"… With the piped input, "echo hello | socat - udp:127.0.0.1:5000", the only difference is that here the command at least exists after the word hello had been sent – however, again, consecutive runs of this command will not cause any reception at the server, until the server is restarted.

Best Answer

Ok, I think at least I got something with socat - namely, the option fork needs to be appended to the server line:

$ socat - udp4-listen:5000,reuseaddr,fork

... and then, in another terminal, we can call echo piping into socat client line multiple times on command line, as it will exit immediately (well, after half a second :)):

$ echo "hello" | socat - udp-sendto:127.0.0.1:5000
$ echo "hello" | socat - udp-sendto:127.0.0.1:5000
$ echo "hello" | socat - udp-sendto:127.0.0.1:5000

... and going back to the first terminal, we can see that the server has successfully shown all three hellos:

$ socat - udp4-listen:5000,reuseaddr,fork
hello
hello
hello
^C

 

Note that even with a fork-ed socat server, the line echo "hello" | nc -u 127.0.0.1 5000 will still 'lock' as if waiting for user input; however, now after Ctrl-C and re-running the command, i.e.

$ echo "hello" | nc -u 127.0.0.1 5000
^C
$ echo "hello" | nc -u 127.0.0.1 5000
^C
$ echo "hello" | nc -u 127.0.0.1 5000
^C

... the fork-ed socat server will show three hellos without the need to be restarted..

 

Seemingly, this openBSD netcat doesn't have a fork option - but I'm not sure if it has one that is corresponding to it..

Anyways, hope this helps someone,
Cheers!

Related Question