Netcat如何在同一主机上的两个不同终端监听相同端口?

7

为什么我在Debian 8.4上执行以下命令时,在两个不同的终端窗口中执行它时,没有出现“地址已被使用”的错误类型?

netcat -p 1234 -l

我想知道为什么它没有抛出错误,因为它启动了两个监听同一端口的进程。
难道netcat不使用套接字吗?这怎么可能呢?


1
你看过 https://dev59.com/lXI-5IYBdhLWcg3wwLS3 吗? - Mats
是的,但正如这里所说:“多个监听TCP套接字,都绑定到同一个端口,可以共存,前提是它们都绑定到不同的本地IP地址。”只有在套接字绑定到不同的本地IP地址时才可能实现(如果我理解正确的话),而据我所知,这里并非如此。 - Simon
这与编程无关,不适合在 Stack Overflow 上提问。请前往 Super User 或其他相关网站寻求此类问题的帮助。 - xaxxon
2个回答

8
在我的系统上,运行strace nc -l 1234会出现以下结果:
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_REUSEPORT, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(1234), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(3, 1)                            = 0
accept(3, 

因此,套接字使用选项SO_REUSEADDRSO_REUSEPORT进行设置,这允许多个进程绑定到相同的端口和相同的监听地址。请参见man 7 socket该详细答案。此选项的目的是允许一种简单的负载平衡形式:端口的传入连接将被重定向到其中一个进程(似乎是随机的)。


0

-p选项指定的是源端口,而不是监听端口

-l选项将netcat置于监听模式。

在您的示例中,1234-p选项的输入值,而不是-l选项,这意味着没有明确指定监听端口。如果netcat没有失败,那么很可能netcat会绑定到0号端口,这告诉监听套接字绑定到一个随机可用的临时端口。因此,您的两个netcat实例实际上会侦听不同的端口。使用netstat进行验证。

根据Linux manpage for netcat

-l'用于指定nc应该监听传入的连接,而不是发起到远程主机的连接。与-p、-s或-z选项结合使用此选项是错误的。此外,使用-w选项指定的任何超时都将被忽略。 -p source_port指定nc应使用的源端口,受特权限制和可用性限制。在使用-l选项时使用此选项是错误的。 因此,在技术上,您的示例可能从一开始就无效。但是,在某些系统上,包括某些Debian安装程序,取决于您使用哪种netcat版本(特别是传统版本),实际上可能需要同时使用-l和-p,但是您需要交换它们的顺序以正确指定侦听端口,例如:
nc -l -p 1234

5
可以在同一端口上多次监听,例如:nc -l 1234。为什么呢? - iman
2
抱歉,那不是解释的原因:在两个不同的终端中运行nc -l 1234是可以正常工作的。 - a3nm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接