Janne H
Janne H

Reputation: 1683

How to send only one UDP packet with netcat?

I want to send only one short value in a UDP packet, but running the command

echo -n "hello" | nc -4u localhost 8000

I can see that the server is getting the hello stuff but I have to press Ctrl+c to quit the netcat command.

How can I make it quit after sending hello?


Sorry, for the noise, I re-read the man page and found the -q option.

 echo -n "hello" | nc -4u -q1 localhost 8000

works (it quits after 1 second).

For some reason it does not work with -q0.

Upvotes: 166

Views: 316598

Answers (6)

Kenny
Kenny

Reputation: 315

Unfortunately nc is not a unique name for a single tool. To find out which nc you have, look at the first line of output from nc -h. To send a single UDP packet and exit immediately, use the appropriate arguments for your specific nc.

  • GNU nc -uc localhost 8000 <<<hello
  • BSD nc -uq0 localhost 8000 <<<hello
  • traditional nc -uq0 localhost 8000 <<<hello
  • BusyBox nc does not support UDP
  • Others? Please leave a comment!

Related but thankfully not calling themselves nc:

  • nmap: ncat -u --send-only localhost 8000 <<<hello
  • bash: echo hello >/dev/udp/localhost/8000
  • socat - UDP:localhost:8000 <<<hello
  • sendip -p ipv4 -p udp -ud 8000 -d $'hello\n' localhost
  • packetsender -ua localhost 8000 $'hello\n'
  • There are so many more! But the original question was about netcat...

If you want a portable nc wrapper for sending a single UDP packet, try this as nc-udp-oneshot.sh:

#!/bin/sh

helpword=$(nc -h 2>&1 | awk '{print$1;exit}')

case $helpword in
  *GNU*) args=-uc ;;
  *) args=-uq0 ;;
esac
exec nc $args "$@"

Now you can run echo -n hello | ./nc-udp-oneshot.sh with whichever nc happens to be installed. Or xxd -r -p <<<68656c6c6f | ./nc-udp-oneshot.sh for sending more complicated binary data, represented in hex.

Upvotes: 8

Peter Eisentraut
Peter Eisentraut

Reputation: 36729

If you are using bash, you might as well write

echo -n "hello" >/dev/udp/localhost/8000

and avoid all the idiosyncrasies and incompatibilities of netcat.

This also works sending to other hosts, ex:

echo -n "hello" >/dev/udp/remotehost/8000

These are not "real" devices on the file system, but bash "special" aliases. There is additional information in the Bash Manual.

Upvotes: 264

Sajjad Baeidi
Sajjad Baeidi

Reputation: 322

I had the same problem but I use -w 0 option to send only one packet and quit. You should use this command :

echo -n "hello" | nc -4u -w0 localhost 8000

Upvotes: 13

Simon
Simon

Reputation: 537

On a current netcat (v0.7.1) you have a -c switch:

-c, --close                close connection on EOF from stdin

Hence,

echo "hi" | nc -cu localhost 8000

should do the trick.

Upvotes: 17

Evan
Evan

Reputation: 121

Netcat sends one packet per newline. So you're fine. If you do anything more complex then you might need something else.

I was fooling around with Wireshark when I realized this. Don't know if it helps.

Upvotes: 7

TraderJoeChicago
TraderJoeChicago

Reputation: 6315

I did not find the -q1 option on my netcat. Instead I used the -w1 option. Below is the bash script I did to send an udp packet to any host and port:

#!/bin/bash

def_host=localhost
def_port=43211

HOST=${2:-$def_host}
PORT=${3:-$def_port}

echo -n "$1" | nc -4u -w1 $HOST $PORT

Upvotes: 56

Related Questions