8

I would like to use netcat to send a piece of text to the echo service on my server, get the reply then exit, so that I know the connection is still good. so far I've tried:

 echo 'test' | netcat server 7 

this way netcat would wait for more input rather than exit.

How can I make netcat exit after getting reply from the echo service?

10 Answers 10

6

Just tried - slightly different behaviour between netcat-openbsd and netcat-traditional ( ubuntu 16.4). The OpenBSD variant does what you expect, while with the netcat-traditional I need to add the -q 1 to avoid waiting for more input.

echo 'test' | netcat -q 1 server 7
| improve this answer | |
5

Your command should work. It is very similar to some of the examples in the netcat manpage.

This is exactly how netcat is supposed to operate: once it has reached EOF on stdin, it (one-way) closes the connection /to/ the server and then waits for data coming from the server. When the latter closes the connection (the other way: server->client), then netcat stops.

If your netcat command doesn't finish, I suppose there is something strange happening at the network level that keeps the echo server listening for additional input.

You can try out the -q option to force netcat to stop N seconds after EOF is encountered on stdin:

netcat -q1 server echo <<< "test"

(<<< "test" is a bashism, use your echo ... | syntax if you don't use bash)

| improve this answer | |
5

Use this:

cat <(echo command) - | nc host port

The problem is that nc will close the connection immediately after stdin is closed, which is very quick for a simple my_command string, and thus never gets the chance to receive a response. If you pipe a very large file you will see that it might get a response before it's done sending the file.

Enter cat with - as second argument: it makes cat listen on stdin for more content to pipe through after it has sent the contents of the first argument. The first argument is just getting the echo command through cat – it could also be a file with your commands a la cat < file - | ....

The downside of that is now that it stays open until you hit ^C or ^D on the shell. Adding a timeout using -w 1 (OSX netcat) or -i 1 (nmap's ncat) makes it close the connection after 1 second, but it won't exit the process until you enter some character.

This answer is based on this answer to an identical superuser question.

| improve this answer | |
  • cat <(echo command) <(sleep 1) | nc host port causes stdin to stay open as long as the sleep command runs without the need to set nc timeouts or have the user "enter some character". – romanows Jan 19 at 21:27
2

I don't understand your question properly?

The default netcat listener should exit upon receiving input (in this case your echo pipes it to netcat which forwards it to the listener).

If you want the listening Netcat service to stay listening after it receives input:

nc -lk 12345
  • where 12345 is the port number

Most importantly though, please check the man pages for netcat.. they are amazingly useful for all commands...

man nc
| improve this answer | |
1

I know this is a bit old but no other answer worked for me and this did:

echo 'test' | netcat -N $server $port

Notice the -N:

shutdown the network socket after EOF on the input. Some servers require this to finish their work.

Worked for me on both Windows and Linux.

| improve this answer | |
1

I'd recommend socat instead:

echo test | socat -t 10 - tcp:server:7

(here waiting for up to 10 seconds for the server to reply and shutdown)

socat can do much much much more than the various (different and incompatible) implementations of nc/netcat, and generally works more reliably. It's your ultimate plumbing Swiss Army knife.

Quoting the man page for the -t option:

-t<timeout>
When one channel has reached EOF, the write part of the other channel is shut down. Then, socat waits [timeval] seconds before terminating. Default is 0.5 seconds. This timeout only applies to addresses where write and read part can be closed independently. When during the timeout interval the read part gives EOF, socat terminates without awaiting the timeout.

So above, after echo writes test\n, it exits, which closes the pipe. socat sees EOF on its - channel (stdin), then shuts the writing direction of the TCP socket and waits for the remote service to shutdown as well or for 10 seconds of inactivity whichever comes first. The echo service is meant to terminate the connection as soon as the other end has shut down its sending direction, so that command should not take any longer than the time it takes to establish the connection, exchanging the data and shutting down.

With OpenBSD's netcat or its port to Linux which is the default one on recent versions of Debian and derivatives at least, an approximation would be nc -Nw10 server 7 (that's different in that nc's -w is both a connection timeout and an inactivity timeout)

To implement a TCP echo service on port 7777 for testing:

socat tcp-listen:7777,reuseaddr,fork exec:cat,nofork

(the fork to fork a process for each incoming connection, nofork to execute cat directly in that process with its stdin/stdout being the TCP socket, like when using (x)inetd).

Some timing on the loopback interface, with zsh:

$ time echo test | socat -t10 - tcp:localhost:7777
test
echo test  0.00s user 0.00s system 54% cpu 0.001 total
socat -t10 - tcp:localhost:7777  0.00s user 0.01s system 55% cpu 0.009 total
| improve this answer | |
0

sending a ping to Redis and grep the PONG:

echo 'PING' | nc -w 1 server 6379 | grep PONG

Works as Ansible command.

| improve this answer | |
0

Actually, the best way to close gracefully the connection is to send the Content-Length header like following. Client (like curl will close the connection after receiving the data.

DATA="Date: $(date)"; 
LENGTH=$(echo $DATA | wc -c);
echo -e "HTTP/1.1 200 OK\nContent-Length: ${LENGTH}\n\n${DATA}" | nc -l -p 8000;
| improve this answer | |
0

I just check the timeout cmd while trying the nc command, like :

echo "test" | timeout 10 netcat server 7

This waits 10 sec before closing the connection.

| improve this answer | |
-1
(echo 'test'; sleep 1) | netcat server 7 

This keeps the input open for some time to delay netcat ending.

| improve this answer | |

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.