----------------[ Notes on Netcat ]---------------- Many of you experienced confusing "netcat" behavior on our CS Unix systems: netcat would exit before receiving the server's message. Thus working server code would appear broken, and this has cost much valuable debugging time. I apologize for this confusion. The reason for this appears to be that the "nc" command on our Unix machines exits as soon as it reaches the end of the input piped into it, and before the server can respond or its response can be printed. There is a workaround, below, but why would "nc" do it in the first place? The answer turned out to be that "nc" on our Unix machines is NOT Netcat. It is a program called Ncat, which is a part of the Nmap network scanner suite. This program is similar to Netcat but behaves differently in some edge cases. RedHat, in its wisdom, decided to replace the standard Netcat tool with Ncat _and_ still call it "nc". [tahoe:~] 143) ls -l `which nc` lrwxrwxrwx 1 root root 4 Jan 3 11:44 /usr/bin/nc -> ncat I did not know this, and used an actual Netcat to test :( ----------------[ 1. Workaround with ncat ]---------------- One method is to stop Ncat from immediately exiting after its input is done. You can to that with the "cat" command below, saying "first write out this file, then switch to standard input & wait". Ncat won't exit until stdin is done; that will give time for the server to respond, and for ncat to print its response. In the following, I am running "./udp-echo/udpserver 31337" on tahoe in another window, so I should see my requests echoed back byte-for-byte. [tahoe:~] 144) echo -ne '\x01\x02nh' > req [tahoe:~] 145) xxd req 00000000: 0102 6e68 ..nh [tahoe:~] 146) cat req - | nc -u 127.0.0.1 31337 > resp ^D [tahoe:~] 147) xxd resp 00000000: 0102 6e68 ..nh If your responses contain newlines, then you can pipe them straight to xxd rather than to a file ("\n" flushes the buffered standard output). ----------------[ 2. Real Netcat ]---------------- Real Netcat can be downloaded and built on our systems. I did this to check that I was sane, mostly, but here is the transcript. Skip to the end for a useful option, though! [tahoe:cs60] 109) wget http://sourceforge.net/projects/netcat/files/netcat/0.7.1/netcat-0.7.1.tar.bz2 netcat-0.7.1.tar.bz2 100%[=================================================>] 318.05K 1.57MB/s in 0.2s 2017-04-21 19:48:35 (1.57 MB/s) - ‘netcat-0.7.1.tar.bz2’ saved [325687/325687] [tahoe:cs60] 111) tar xvfj netcat-0.7.1.tar.bz2 [tahoe:cs60] 112) cd netcat-0.7.1/ [tahoe:netcat-0.7.1] 115) ./configure checking build system type... x86_64-unknown-linux-gnu checking host system type... x86_64-unknown-linux-gnu checking target system type... x86_64-unknown-linux-gnu [tahoe:netcat-0.7.1] 116) make make all-recursive make[1]: Entering directory '/net/people/sergey/cs60/netcat-0.7.1' Making all in m4 // Now that the netcat binary is made, I copy it into a directory // in my path where I keep my own binaries and scripts, ~/bin/ [tahoe:netcat-0.7.1] 119) cd src [tahoe:src] 121) cp -i netcat ~/bin/ // Checking that I'll really get it when I run "netcat": [tahoe:~] 123) which netcat ~/bin/netcat [tahoe:~] 132) echo -ne '\x01\x02\x03x' | netcat -u 127.0.0.1 31337 > resp ^C [tahoe:~] 133) xxd resp 00000000: 0102 0378 ...x It works. The original Netcat does not exit until you stop it, because it cannot know how much data the server will send back and when. So it remains ready to print more, as it should. The kind of behavior that Ncat shows---exiting on EOF in stdin---is also possible in Netcat, but requires the "-c" option. Finally, with "-x", the original Netcat shows input and output in hex, immediately: [tahoe:~] 158) echo -ne '\x01\x02\x03x' | netcat -x -u 127.0.0.1 31337 Sent 4 bytes to the socket 00000000 01 02 03 78 ...x xReceived 4 bytes from the socket 00000000 01 02 03 78 ...x ^C I apologize for this confusion. Note that in MacOS the meaning of the "-x" option is different, but it behaves as Netcat should.