1

I need to use nc in a weird way, where I want the server to first send a file, and then receive a file, and this repeats. I would like to have every instance of the server server close after some seconds. How can I do this in a script? I already have a client that can interact with the server.

5

Some netcat implementations have a timeout option. For the one on my system, it is -w. Thus

$ nc -l -p 2000 -w 5

will listen on port 2000 and exit in 5 seconds unless a connection is attempted on that port.

2
  • most nc's suck these days, though, because they are not kept. ncat - by the nmap people - is the exception, i think. and, of course, there is socat if you have the determination to learn a new programming language.
    – mikeserv
    Jan 5 '16 at 15:06
  • 1
    This is incorrect. According to man nc(1): "The -w flag has no effect on the -l option, i.e. nc will listen forever for a connection, with or without the -w flag" Mar 17 '19 at 11:38
2

Because of the documentation :The -w flag has no effect on the -l option, i.e. nc will listen forever for a connection, with or without the -w flag

I tried nc ncat socat, no one can set timeout for server mode.

As far as I know, only busybox nc can follow -w option in server mode.

So you have to download busybox which compiled with CONFIG_NC_SERVER=y option, or compile it by your self.

So that you can

$busybox nc -w 10 -l -p 9999

But my system's busybox didn't compile with CONFIG_NC_SERVER=y option, and I don't want compile it. So I use this solution:

portnum=9999
(sleep 10 ;echo "T" | nc -w 1 127.0.0.1 $portnum) | nc -N -l -p $portnum 

After 10 seconds, send "T" to localhost:9999

The full code is

#!/bin/sh
portnum=9999
testmsg="Hello_World"
if [ "$( (sleep 10 ;echo "T" | nc -w 1 127.0.0.1 $portnum) | nc -N -l -p $portnum )" = $testmsg ]; then
  echo "Test pass"
else
  echo "Test not pass"
fi

If server received Hello_World in 10 seconds, it will print Test pass. Otherwise print Test not pass

You can try open another console, and type

echo "Hello_World" | nc -w 1 127.0.0.1 9999

to test it.

1

Using bash timeout:

$ timeout 3s nc -l -p 2000
5
  • That will kill the nc after 3s even if it had accepted a connection.
    – mosvy
    Dec 25 '19 at 7:47
  • ... which may actually be what the OP was asking, but it's not what the other answers do.
    – mosvy
    Dec 25 '19 at 7:58
  • actually I didn't try to accept connection... it was perfect for my use case (I need the port to accept connection just to make remote script happy).
    – chenchuk
    Dec 25 '19 at 19:04
  • You should clearly explain what it's doing. The question is unclear and people come here with different ideas -- in this case the other two answers do something completely different than yours: they will wait up to N seconds for a connection, and if a connection happens within the N seconds, they will accept it and will continue servicing it even after the N seconds have passed.
    – mosvy
    Dec 25 '19 at 22:39
  • in my use case, I got remote ansible script which check 9092 port (kafka) and fails because kafka fails. since I don't care about this, I need a mechanism to make the port open. using nc in a loop did the job for me. ansinle tries to reach the port for 5 min, I made it to make ansible happy and continue execution. (after this I fix Kafka which is not relevant here)
    – chenchuk
    Dec 26 '19 at 8:21
1

As stated by peterph the timeout (-w) while listening (-l) for connections works (only) with traditional nc implementations.

On Ubuntu such an implementation can be installed with apt install netcat-traditional and called with nc.traditional.

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.