为什么以下命令(在我的Debian 8.4机器上)没有输出类型"地址已在使用的错误"当我从两个不同的终端执行它时?
netcat -p 1234 -l
我想知道为什么它不会抛出错误,因为它启动了两个进程侦听同一个端口 netcat没有使用套接字吗?怎么可能?
答案 0 :(得分:2)
-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
答案 1 :(得分:1)
在我的系统上,运行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
或this detailed answer。该选项的目的是允许一种简单的负载平衡形式:与端口的传入连接将被重定向到进程之一(显然是随机的)。