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

How to listen for multiple tcp connection using nc

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

nc -l -p 12345

netcat 无法同时连接。你应该使用像 ucspi-tcp's tcpserver tool or leverage xinetd 这样的东西,因为你在 Linux.

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

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

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

我推荐 socat 作为 nc 替代方案。

OP的问题,socat - TCP-LISTEN:12345,fork,reuseaddr可以解决。

ncat可以做到。

例如ncat --broker --listen -p 12345 会将所有传入消息分发给所有其他客户端(将其视为集线器)。

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

首先,似乎有不同版本的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

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

为了理解这一点,假设您开始使用 $ nc -l -p 4444 -v 监听 4444 端口。现在,如果您检查 $ 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。现在,尝试 运行ning $ 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

没有 -kncat 的行为与 nc 相同。

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

对于此示例,我使用了 ncnc.traditional (v1.10-41.1+b1),以及 ncat (7.80)。

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

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

这将同时接受多个连接。

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

nc localhost 12345