39

How to create a TCP connection using nc which listens to multiple hosts?

nc -l -p 12345
livibetter
  • 19,832
  • 3
  • 42
  • 42
Aman Jain
  • 895
  • 2
  • 10
  • 19
  • 1
    you may want to clarify whether you are looking to create multiple TCP connections **to** `nc` (e.g. from a bunch of other clients) or whether you want to listen **on** multiple TCP/IP addresses instead of listening on one and make the title and the text compliant – Hans Z. Apr 20 '15 at 14:40
  • 1
    @HansZ. multiple tcp connection, so that multiple client connect to a single socket. – Aman Jain Apr 21 '15 at 15:44

7 Answers7

23

Simultaneous connections are not possible with netcat. You should use something like ucspi-tcp's tcpserver tool or leverage xinetd since you're on Linux.

See: https://superuser.com/questions/232747/netcat-as-a-multithread-server

Consecutive connections could be handled through a shell script that restarts netcat after it finishes.

Community
  • 1
  • 1
Hans Z.
  • 50,496
  • 12
  • 102
  • 115
  • 5
    nc -k will handle incoming connections when the previous finishes, and can still accept a second connection while handling the first. – wizulus Mar 17 '17 at 20:47
  • 1
    Thanks @Hans Z. .. Could you provide the example as there is no example given in that link –  Jan 21 '19 at 02:19
  • Author did not even ask for simultaneous connections. – excitoon Feb 14 '23 at 22:21
20

I recommend socat as nc alternative.

For OP's problem, socat - TCP-LISTEN:12345,fork,reuseaddr can do the job.

Roger Lipscombe
  • 89,048
  • 55
  • 235
  • 380
dyng
  • 2,854
  • 21
  • 24
20

ncat can do it.

E.g. ncat --broker --listen -p 12345 will distribute all incoming messages to all other clients (think of it as a hub).

masterxilo
  • 2,503
  • 1
  • 30
  • 35
  • that's pretty limited/specialized, but sure is handy to know – sehe Jul 29 '18 at 22:58
  • 2
    To clarify, `ncat -l -p 12345` does what the OP wanted. The example using `--broker` is interesting, but not relevant to this specific question. – Todd Owen Oct 19 '18 at 06:05
  • @ToddOwen incorrect. Just tried, the second connection is always connection refused. Using --broker works. – Code Wiget Nov 28 '18 at 17:15
  • 3
    @Ryan Would you mind trying `ncat -k -l -p 12345`? You're right, the command line I posted above does not work, but `--broker` will cause the listening process to not output anything to stdout, instead copying all data it receives back to the (other) clients, which is definitely not what the OP asked for. – Todd Owen Nov 28 '18 at 21:21
  • 2
    @ToddOwen Unfortunately, "Ncat: UDP mode does not support the -k or --keep-open options, except with --exec or --sh-exec. QUITTING." – Code Wiget Dec 04 '18 at 15:43
  • @Ryan It looks like you are adding `-u` to select the UDP protocol instead of the default TCP. According to [this answer](https://stackoverflow.com/a/7696956/154770), it doesn't support that (nor does it support `--broker` with UDP). However, check out the [workaround](https://stackoverflow.com/a/53622433/154770) which I just posted. – Todd Owen Dec 04 '18 at 22:33
  • 1
    This. is. amazing. I've been looking for a simple tool that can do this for almost a year now. – James M. Lay Feb 15 '19 at 16:57
13

-k
Forces nc to stay listening for another connection after its current connection is completed. It is an error to use this option without the -l option.

rene
  • 41,474
  • 78
  • 114
  • 152
excitoon
  • 328
  • 3
  • 11
  • 10
    This does not answer the OP's question. They wanted to be able to listen for two or more connections at the same time, not for back-to-back connections. – cascading-style Feb 23 '17 at 20:03
  • Yeah, and it works exactly as requested. Once first connection is closed it will print packets from next one. Otherwise you would get a mess with data from different connections. – excitoon Mar 04 '17 at 08:27
  • 3
    This should be the accepted answer. With -k, netcat will accept multiple connections, but will only handle them one at a time. This was the exact answer I was looking for when I landed on this page. – wizulus Mar 17 '17 at 20:46
  • 1
    I just tried this and found it (a) accepts multiple simultaneous connections, and (b) prints all the data as it is received. This is different from what some commenters above have observed, and I wonder if they were actually seeing the effects of buffering somewhere in the system? – Todd Owen Nov 28 '18 at 21:15
  • 1
    @wizulus I can't think why anyone would want to specifically avoid having two connections at the same time. Maybe that's what you want, I'm not disputing that, but I don't see any evidence that that's what OP wants. It's good that you got your answer, but it was a fluke, and I for one don't think the answer should be upvoted for answering the wrong question. – David Knipe Aug 23 '19 at 21:25
  • 1
    @ToddOwen I saw the same behaviour as excitoon. Also, excitoon makes a good point: If several connections are present at the same time and netcat only has one STDIN and one STDOUT, how do you separate the data from/to one client from the data from/to another? – David Knipe Aug 23 '19 at 21:32
  • @DavidKnipe I understand the confusion. I don't specifically want to avoid two connections at the same time. I want to avoid having one connection rejected when two hosts connect simultaneously. Without -k, nc would only accept a connection from one host, and even if you run nc again right away, there is always a period of time when there is no one listening. Good discussion tho. – wizulus Sep 05 '19 at 13:46
  • @cascading-style Did you just make up "at the same time"? :)))) – excitoon Feb 14 '23 at 22:19
4

using nc it is not possible to open parallel connections to same port, however you can trick nc to open multiple connections to same port.

To understand this, lets say you start listening on 4444 port using $ nc -l -p 4444 -v. Now, if you check output of $ netstat -anp | grep 4444 you will get its state as LISTEN and in here its pid is 3410.

tcp        0      0 0.0.0.0:4444            0.0.0.0:*               LISTEN      3410/nc

Now, after it gets connected to client, lets say you run $ nc localhost 4444 -v, its state will get changed into ESTABLISHED. Now, try running $ netstat -anp | grep 4444 you will get its state as ESTABLISHED, see for same pid 3410, and a client process with pid 3435

tcp        0      0 127.0.0.1:46678         127.0.0.1:4444          ESTABLISHED 3435/nc
tcp        0      0 127.0.0.1:4444          127.0.0.1:46678         ESTABLISHED 3410/nc

Please note that there is no available listening port, so you can't have another client process. However if you run again $ nc -l -p 4444 -v you can have a listening port and can have multiple client process.

see netstat -anp | grep 4444 output after you start listening to same port.

tcp        0      0 0.0.0.0:4444            0.0.0.0:*               LISTEN      3476/nc 
tcp        0      0 127.0.0.1:46678         127.0.0.1:4444          ESTABLISHED 3435/nc 
tcp        0      0 127.0.0.1:4444          127.0.0.1:46678         ESTABLISHED 3410/nc

see netstat -anp | grep 4444 output after you attach new client to same port.

tcp        0      0 127.0.0.1:4444          127.0.0.1:46694         ESTABLISHED 3476/nc 
tcp        0      0 127.0.0.1:46678         127.0.0.1:4444          ESTABLISHED 3435/nc 
tcp        0      0 127.0.0.1:4444          127.0.0.1:46678         ESTABLISHED 3410/nc 
tcp        0      0 127.0.0.1:46694         127.0.0.1:4444          ESTABLISHED 3483/nc

You can say connections behavior is like:

SERVER_PROCESS_1 <---> CLIENT_PROCESS_1
SERVER_PROCESS_2 <---> CLIENT_PROCESS_2

so, you can write some script to simulate this behavior, or use this bash script to modify.

#!/usr/bin/bash
lport="4444"
i=0;
while [ true ]; do
    echo "opening socket $(( i++ ))";
    if [[ "$(ss sport = :$lport -l -H | wc -l)" -eq 0 ]]; then
        nc -l -vv -p $lport & 
        #do something else to process or attach different command to each diff server process
    fi;
    if [[ "$(ss sport = :$lport -l -H | wc -l)" -ne 0 ]]; then
        watch -n 0.1 -g "ss sport = :$lport -l -H" > /dev/null;
    fi;
    if [[ i -eq 10 ]]; then
        break;
    fi;
done;

in here every time client consume a connection this script will start new listen socket.

This behavior is however can be changed in ncat (here, using -k)as you can analyze the with below example:

server is started using $ ncat -l -p 4444 -v -4 -k and 3 clients are started using $ ncat -4 localhost 4444. Now output for $ netstat -anp | grep 4444 is:

tcp        0      0 0.0.0.0:4444            0.0.0.0:*               LISTEN      3596/ncat
tcp        0      0 127.0.0.1:4444          127.0.0.1:46726         ESTABLISHED 3596/ncat
tcp        0      0 127.0.0.1:46726         127.0.0.1:4444          ESTABLISHED 3602/ncat
tcp        0      0 127.0.0.1:46722         127.0.0.1:4444          ESTABLISHED 3597/ncat
tcp        0      0 127.0.0.1:4444          127.0.0.1:46724         ESTABLISHED 3596/ncat
tcp        0      0 127.0.0.1:4444          127.0.0.1:46722         ESTABLISHED 3596/ncat
tcp        0      0 127.0.0.1:46724         127.0.0.1:4444          ESTABLISHED 3601/ncat

Every time new client connect, server fork its process to attach to client, so each server process is using same pid. So output of server in this way is shared to every attached clients, however each client can send individual message to server.

You can say connections behavior is like:

SERVER_PROCESS_1 <---> CLIENT_PROCESS_1
SERVER_PROCESS_1 <---> CLIENT_PROCESS_2
SERVER_PROCESS_1 <---> CLIENT_PROCESS_3

without -k, ncat will behave same as nc.

Benefits or loses can be defined on how they are to be needed.

For this example, i used nc or nc.traditional (v1.10-41.1+b1), and ncat (7.80).

dinesh saini
  • 431
  • 5
  • 8
0

This is an incomplete answer, because I haven't got it working. Arguably more of a question, in fact. Maybe someone else can finish it off.

First of all, it seems there are different versions of netcat. I'm on Ubuntu, so I've probably got the version that came with Ubuntu. When I nc -h, it says this:

OpenBSD netcat (Debian patchlevel 1.187-1ubuntu0.1)

When I run man nc, it says this:

-F      Pass the first connected socket using sendmsg(2) to stdout and exit.  This
        is useful in conjunction with -X to have nc perform connection setup with
        a proxy but then leave the rest of the connection to another program (e.g.
        ssh(1) using the ssh_config(5) ProxyUseFdpass option).

It seems to me that this means that, instead of doing the usual thing with stdin and stdout, it just prints something to stdout. That something could then be used by another process to do the actual connection to the client.

Unfortunately, -F has no effect that I can see. So maybe I'm doing it wrong. Or maybe there's some secret pipe somewhere that I have to listen to, or a supplementary argument they forgot to document. Or maybe I happen to have a broken build of netcat, and it works for everyone else who's on Ubuntu.

In combination with the -k option (or, failing that, a while-true loop), this would allow many different clients to have separate connections. Suppose you have an executable called handle_connection, which takes as arguments an in file descriptor from a client and an out file descriptor to the client, and spawns a subprocess which communicates with the client. Then the server script might look like this:

nc -lkF $host $port | while read in out ; do
    handle_connection $in $out ;
done
David Knipe
  • 3,417
  • 1
  • 19
  • 19
0

ncat can do it, but the correct command with ncat is:

ncat --keep-open --listen -p 12345

This will accept multiple connections at the same time.

You can then send the data with multiple clients. e.g. open in two or more terminals, and try typing there:

nc localhost 12345