Sim*_*mon 6 sockets tcp netcat
为什么当我从两个不同的终端执行以下命令(在我的 Debian 8.4 机器上)时,它不会输出“地址已使用”类型的错误?
netcat -p 1234 -l
Run Code Online (Sandbox Code Playgroud)
我想知道为什么它不会抛出错误,因为它启动了两个进程侦听同一个端口。
netcat 不使用套接字吗?这怎么可能?
在我的系统上,运行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,
Run Code Online (Sandbox Code Playgroud)
因此,套接字是使用选项SO_REUSEADDR
和来设置的SO_REUSEPORT
,它允许多个进程绑定到相同的端口和相同的侦听地址。请参阅man 7 socket
或这个详细答案。此选项的目标是允许一种简单的负载平衡形式:端口的传入连接将被重定向到其中一个进程(显然是随机的)。
该-p
选项指定源端口,而不是侦听端口。
该-l
选项将 netcat 置于监听模式。
在您的示例中,1234
是选项的输入值-p
,而不是-l
选项,这意味着没有指定显式侦听端口。如果 netcat 没有失败,那么很可能 netcat 绑定到端口 0,这告诉侦听套接字绑定到随机可用的临时端口。因此,您的两个 netcat 实例实际上会侦听不同的端口。使用netstat来验证。
-l' 用于指定 nc 应侦听传入连接而不是发起与远程主机的连接。将此选项与 -p、-s 或 -z 选项结合使用是错误的。此外,使用 -w 选项指定的任何超时都将被忽略。
-p source_port
指定 nc 应使用的源端口,但受权限限制和可用性的限制。 将此选项与 -l 选项结合使用是错误的。
因此从技术上讲,您的示例可能一开始就无效。
然而,在某些系统上,包括一些 Debian 安装,根据您使用的 netcat 风格(特别是传统风格),您实际上可能需要一起使用-l
和-p
,但您需要交换它们的顺序才能正确指定侦听端口,例如:
nc -l -p 1234
Run Code Online (Sandbox Code Playgroud)