10

I'm trying to send a message through netcat. After sending the message, netcat must terminate.

I've tried the following:

cat tsmmessage.bin | nc -u localhost 4300
nc -u localhost 4300 < message.bin

The -q option states:

-q seconds

after EOF on stdin, wait the specified number of seconds and then quit. If seconds is negative, wait forever.

But

nc -q0 -u localhost 4300 < message.bin

also doesn't work.

What am I missing?

6

Assuming that after sending EOF connection will stay idle, you can use -w timeout option, which works for timeout being equal to zero (unlike stupid -q option...)

cat tsmmessage.bin | nc -u localhost 4300 -w0
  • 1
    This is the correct answer and must be the accepted one rather than -q. – ccpizza Nov 13 '17 at 18:07
  • zero time out doesn't work on my machine (debian stretch). it says invalid wait-time 0 – Anubis Apr 20 '18 at 10:47
3

Without the -q flag your instance of netcat will wait forever. There's no "end of stream" message with UDP so there is no way for netcat to know that both stdin and the network connection have finished.

For example, using TCP/IP this works as expected:

nc -l localhost 4300                     # Window 1
nc localhost 4300 </etc/group            # Window 2

But as you have determined, using UDP/IP this never ends:

nc -u -l localhost 4300                  # Window 1
nc -u localhost 4300 </etc/group         # Window 2

This is where the -q flag comes in. But unfortunately it doesn't accept a value of 0. It also won't accept non-integer values. Here is the best alternative I can offer without recourse to timeout or some other external utility:

nc -u -l localhost 4300                  # Window 1
nc -q 1 -u localhost 4300 </etc/group    # Window 2

Even here, it's not possible to have the listening netcat time out gracefully. (The -w timeout option is ignored, and -q is irrelevant.) Something like this might be of use in a practical situation, so that the netcat is killed after 90 seconds:

timeout 90 nc -u -l localhost 4300       # Window 1
nc -q 1 -u localhost 4300 </etc/group    # Window 2
  • -q 0 works for me. – AlikElzin-kilaka Nov 11 '18 at 8:52
  • @AlikElzin-kilaka doesn't work for me though. You're definitely using UDP in your tests? What version of netcat do you have? You're probably on a more recent version. – roaima Nov 11 '18 at 9:01
-1

Stumbled upon this when Googling regarding pretty much the same problem. It turned out the issue was that netcat got killed by bash right after all the data got sucked in, without getting any chance to receive the response.

My solution to this was to add some delay after piping the data, like this:

(echo INFO; sleep 1) | nc redis.service.consul 6379

With a file this can look like:

(cat tsmmessage.bin; sleep 5) | nc -u localhost 4300
  • netcat still doesn't close when sleep finishes. I would expect the first command line to return to the prompt after 1 second, but it doesn't. – Frank Kusters Jun 1 '16 at 9:35
  • how about adding -q 1? i.e. (echo INFO; sleep 1) | nc -q 1 redis.service.consul 6379? – SkyWriter Jun 1 '16 at 9:36
  • With -q everything works, even the example in my original question. I've moved to a newer version of Ubuntu since then, maybe that causes the difference. – Frank Kusters Jun 1 '16 at 10:00
  • That's weird. Anyways, glad we both found a way around this :) – SkyWriter Jun 1 '16 at 17:32
-2

udp

# listen on receiver
nc -u -l localhost -p 4300

# sender
cat tsmmessage.bin | nc -u -N -q 0 localhost 4300

tcp

# listen on receiver
nc -l localhost -p 4300

# sender
cat tsmmessage.bin | nc -N localhost 4300

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.