为什么我在Debian 8.4上执行以下命令时,在两个不同的终端窗口中执行它时,没有出现“地址已被使用”的错误类型?
netcat -p 1234 -l
我想知道为什么它没有抛出错误,因为它启动了两个监听同一端口的进程。
难道netcat不使用套接字吗?这怎么可能呢?
为什么我在Debian 8.4上执行以下命令时,在两个不同的终端窗口中执行它时,没有出现“地址已被使用”的错误类型?
netcat -p 1234 -l
我想知道为什么它没有抛出错误,因为它启动了两个监听同一端口的进程。
难道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,
因此,套接字使用选项SO_REUSEADDR
和SO_REUSEPORT
进行设置,这允许多个进程绑定到相同的端口和相同的监听地址。请参见man 7 socket
或该详细答案。此选项的目的是允许一种简单的负载平衡形式:端口的传入连接将被重定向到其中一个进程(似乎是随机的)。
-p
选项指定的是源端口,而不是监听端口。
-l
选项将netcat置于监听模式。
在您的示例中,1234
是-p
选项的输入值,而不是-l
选项,这意味着没有明确指定监听端口。如果netcat没有失败,那么很可能netcat会绑定到0号端口,这告诉监听套接字绑定到一个随机可用的临时端口。因此,您的两个netcat实例实际上会侦听不同的端口。使用netstat进行验证。
nc -l -p 1234
nc -l 1234
。为什么呢? - imannc -l 1234
是可以正常工作的。 - a3nm