netcat如何从两个不同的终端监听同一主机上的同一端口?

时间:2016-06-01 13:48:36

标签: sockets tcp netcat

为什么以下命令(在我的Debian 8.4机器上)没有输出类型"地址已在使用的错误"当我从两个不同的终端执行它时?

netcat -p 1234 -l

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

2 个答案:

答案 0 :(得分:2)

-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

答案 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_REUSEADDRSO_REUSEPORT设置了套接字,这允许多个进程绑定到相同的端口和相同的侦听地址。请参阅man 7 socketthis detailed answer。该选项的目的是允许一种简单的负载平衡形式:与端口的传入连接将被重定向到进程之一(显然是随机的)。