如何使用nc监听多个tcp连接

时间:2015-04-19 09:36:15

标签: linux tcp netcat

如何使用监听多个主机的nc创建TCP连接?

nc -l -p 12345

7 个答案:

答案 0 :(得分:16)

netcat无法同时连接。您应该使用ucspi-tcp tcpserver工具或利用xinetd之类的内容,因为您使用的是Linux。

请参阅:https://superuser.com/questions/232747/netcat-as-a-multithread-server

连续连接可以通过在完成后重新启动netcat的shell脚本来处理。

答案 1 :(得分:11)

ncat --broker --listen -p 12345可以做到。

E.g。 { "_id" : ObjectId("5a30ee450889c5f0ebc21116"), "academicyear" : "2017-18", "fid" : "be02", "fname" : "ABC", "fdept" : "Comp", "degree" : "BE", "class" : "1", "sem" : "8", "dept" : "Comp", "section" : "Theory", "subname" : "BDA", "fbValueList" : [ { "_id" : ObjectId("5a30eecd3e3457056c93f7af"), "score" : 20, "rating" : "Fair" }, { "_id" : ObjectId("5a30eefd3e3457056c93f7b0"), "score" : 10, "rating" : "Fair" }, { "_id" : ObjectId("5a337e53341bf419040865c4"), "score" : 88, "rating" : "Excellent" }, { "_id" : ObjectId("5a337ee2341bf419040865c7"), "score" : 75, "rating" : "Very Good" }, { "_id" : ObjectId("5a3380b583dde50ddcea350e"), "score" : 72, "rating" : "Very Good" } ] }, { "_id" : ObjectId("5a3764f1bc19b77dd9fd9a57"), "academicyear" : "2017-18", "fid" : "be02", "fname" : "ABC", "fdept" : "Comp", "degree" : "BE", "class" : "1", "sem" : "5", "dept" : "Comp", "section" : "Theory", "subname" : "BDA", "fbValueList" : [ { "_id" : ObjectId("5a3764f1bc19b77dd9fd9a59"), "score" : 88, "rating" : "Excellent" }, { "_id" : ObjectId("5a37667aee64bce1b14747d2"), "score" : 74, "rating" : "Good" }, { "_id" : ObjectId("5a3766b3ee64bce1b14747dc"), "score" : 74, "rating" : "Good" } ] } 会将所有传入的消息分发给所有其他客户端(将其视为集线器)。

答案 2 :(得分:8)

  

-k
      强制nc在当前连接完成后继续侦听另一个连接。如果没有-l选项,则使用此选项会出错。

答案 3 :(得分:8)

我建议将socat作为nc替代方案。

对于OP的问题,socat - TCP-LISTEN:12345,fork,reuseaddr可以完成这项工作。

答案 4 :(得分:1)

使用nc无法打开到同一端口的并行连接,但是您可以欺骗nc打开到同一端口的多个连接。

要理解这一点,可以说您开始使用4444$ nc -l -p 4444 -v端口上进行监听。现在,如果您检查$ netstat -anp | grep 4444的输出,您将得到其状态为LISTEN,这里的pid为3410。

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

现在,将其连接到客户端后,可以说您运行$ nc localhost 4444 -v,其状态将变为ESTABLISHED。现在,尝试运行$ netstat -anp | grep 4444,您将获得其状态为ESTABLISHED,请参见相同的pid 3410,以及带有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

请注意,没有可用的侦听端口,因此您不能有其他客户端进程。但是,如果再次运行$ nc -l -p 4444 -v,则可以有一个侦听端口,并且可以有多个客户端进程。

开始监听同一端口后,请查看netstat -anp | grep 4444输出。

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
将新客户端附加到同一端口后,

请参见netstat -anp | grep 4444输出。

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

您可以说连接行为类似于:

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

因此,您可以编写一些脚本来模拟这种行为,或使用此bash脚本进行修改。

#!/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;

在此,每次客户端使用连接时,此脚本将启动新的侦听套接字。

不过,可以在ncat中更改此行为(在这里,使用-k),因为您可以通过以下示例进行分析:

服务器使用$ ncat -l -p 4444 -v -4 -k启动,而3个客户端使用$ ncat -4 localhost 4444启动。现在$ netstat -anp | grep 4444的输出是:

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

每次新客户端连接时,服务器都会分叉其进程以附加到客户端,因此每个服务器进程都使用相同的pid。因此,以这种方式将服务器的输出共享给每个连接的客户端,但是每个客户端都可以向服务器发送单独的消息。

您可以说连接行为类似于:

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

如果没有-k,则ncat的行为与nc相同。

可以根据需要对收益或损失进行定义。

在此示例中,我使用了ncnc.traditional(v1.10-41.1 + b1)和ncat(7.80)。

答案 5 :(得分:0)

这是一个不完整的答案,因为我没有用。实际上,可以说更多的是一个问题。也许其他人可以完成它。

首先,似乎有不同版本的netcat。我在Ubuntu上,所以我可能已经有了Ubuntu随附的版本。当我nc -h时说:

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

当我运行man nc时,它会说:

-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).

在我看来,这意味着,与使用stdin和stdout进行常规操作不同,它只是向stdout打印了一些内容。然后,其他进程可以使用某些东西来建立与客户端的实际连接。

不幸的是,-F没有任何作用。所以也许我做错了。也许有一些我必须听的秘密管道,或者是他们忘记记录的补充论点。也许我碰巧有一个破烂的netcat版本,它适用于Ubuntu上的其他所有人。

结合使用-k选项(或者失败的话,进行while-true循环),这将允许许多不同的客户端具有单独的连接。假设您有一个名为handle_connection的可执行文件,该文件将来自客户端的输入文件描述符和来自客户端的输出文件描述符作为参数,并生成一个与客户端进行通信的子进程。然后服务器脚本可能如下所示:

nc -lkF $host $port | while read in out ; do
    handle_connection $in $out ;
done

答案 6 :(得分:0)

ncat 可以做到,但是 ncat 的正确命令是:

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

这将同时接受多个连接。

然后您可以向多个客户端发送数据。例如在两个或多个终端中打开,然后尝试在那里输入:

nc localhost 12345