尽管进程正在侦听,但 UDP 端口无法访问

尽管进程正在侦听,但 UDP 端口无法访问

我正在尝试通过 UDP 端口 6666 进行通信(目标是为 netconsole 设置侦听器,但这与此处无关)。

在聆听方面,nc -luv 6666.在发送端,nc -uv LISTENER_IP 6666.我可以发送和接收,生活很美好。

现在,我让侦听器保持运行,但杀死发送者并启动另一个发送者。它立即终止。网络跟踪显示接收服务器发送了一个ICMP 端口不可达。然而,听者仍然在听:

$ sudo ss -nlup|grep 6666
UNCONN     0      0           :::6666                    :::*                   users:(("nc",pid=3417,fd=3))

我杀死接收器并运行一个新的。一切都像以前一样工作,直到我杀死发件人。

发送方和接收方是同一网络上的物理机器。物理机和其上运行的虚拟机之间的相同测试会产生相同的结果。

如何解释这种行为?

答案1

由于 UDP“连接”的工作方式,这是预期的行为。这是讨论的在里面nc6(1)手册页中socat(“UDP”),但也适用于nc

netcat6 中的 UDP 支持在连接和侦听模式下都运行良好。当在侦听模式下使用 UDP 时,netcat6 接受来自与指定的可选地址和/或端口(如果已指定)相匹配的任何源的 UDP 数据包。但是,一旦收到第一个数据包,netcat6 以后将只接收来自该客户端的数据包。这是通过将 UDP 套接字置于“已连接”状态来完成的(请参阅 udp(4) 和 connect(2))。来自其他来源的数据包将被内核丢弃,并发送 ICMP 不可达响应。

当使用 UDP 连接到远程主机时,无论远程服务器是否正在侦听,nc6 都会报告连接已打开。这是因为 UDP 是无连接协议,因此实际上不需要建立连接。然而,在发送第一个数据包后,服务器可能会回复 ICMP 无法到达的响应,导致 nc6 退出并显示“连接被拒绝”错误消息。

当您从发送方连接时,会选择随机的 UDP 源端口。然后接收器绑定到该特定对host:port,并且从那时起将不会侦听任何其他连接。要解决此问题,您需要强制发送方始终使用同一端口。我用socat这个例子是因为它更容易做到:

听众:

# socat -d -d UDP-LISTEN:6666 stdout
2018/01/29 22:02:02 socat[20969] N listening on UDP AF=2 0.0.0.0:6666
2018/01/29 22:02:07 socat[20969] N accepting UDP connection from AF=2 10.100.0.5:39000
2018/01/29 22:02:07 socat[20969] N using stdout for reading and writing
2018/01/29 22:02:07 socat[20969] N starting data transfer loop with FDs [5,5] and [1,1]
hello
bye
hello1
bye1

发件人:

# socat -d -d stdin UDP:listener-host:6666
2018/01/29 22:01:56 socat[8237] N using stdin for reading and writing
2018/01/29 22:01:56 socat[8237] N opening connection to AF=2 10.100.0.3:6666
2018/01/29 22:01:56 socat[8237] N successfully connected from local address AF=2 10.100.0.5:39000
2018/01/29 22:01:56 socat[8237] N starting data transfer loop with FDs [0,0] and [5,5]
hello
bye
2018/01/29 22:02:10 socat[8237] N socket 1 (fd 0) is at EOF    
2018/01/29 22:02:10 socat[8237] N exiting with status 0

 

# socat -d -d stdin UDP:listener-host:6666
2018/01/29 22:02:13 socat[8238] N using stdin for reading and writing
2018/01/29 22:02:13 socat[8238] N opening connection to AF=2 10.100.0.3:6666
2018/01/29 22:02:13 socat[8238] N successfully connected from local address AF=2 10.100.0.5:57125
2018/01/29 22:02:13 socat[8238] N starting data transfer loop with FDs [0,0] and [5,5]
hello
2018/01/29 22:02:16 socat[8238] E read(5, 0x5619f9b09330, 8192): Connection refused
2018/01/29 22:02:16 socat[8238] N exit(1)

 

# socat -d -d stdin UDP:listener-host:6666,sourceport=39000
2018/01/29 22:05:17 socat[8280] N using stdin for reading and writing
2018/01/29 22:05:17 socat[8280] N opening connection to AF=2 10.100.0.3:6666
2018/01/29 22:05:17 socat[8280] N successfully connected from local address AF=2 10.100.0.5:39000
2018/01/29 22:05:17 socat[8280] N starting data transfer loop with FDs [0,0] and [5,5]
hello1
bye1
2018/01/29 22:05:23 socat[8280] N socket 1 (fd 0) is at EOF
2018/01/29 22:05:24 socat[8280] N exiting with status 0

正如您所看到的,发送方的源端口发生了变化,但如果我强迫它重用它可以工作的相同端口。

相关内容