我正在尝试调试家庭网络中的连接问题。为此,我使用 Netcat 来确定两台机器是否可以通过特定端口上的 UDP 相互通信。
在接收端,我使用
sudo nc -ul <port>
在发送方
echo "message" | nc -u <reveiver-hostname> <port>
发生以下情况
- 接收方显示“消息”
- 发送者从未完成 nc 命令,只是挂起
- 我退出发送命令(Ctrl-C)
- 我又发了一条消息
- 接收方未收到此消息
- 发送程序不挂起并立即退出
- 我退出接收器上的监听命令并重新启动它
- 循环重复
总之,使用“nc listen”我只能传输一条消息。如果收到消息,则发送命令不会退出。
我的期望是发送命令执行完后退出。它是 UDP,所以除了发送几个数据包就完事了之外,做任何事情都没有意义。但事实似乎并非如此。在接收方,我希望它能接收任意数量的数据包并将它们显示在控制台上,无论它们从哪里或何时到达。
看起来要么是出现了奇怪的错误,要么是我从根本上误解了它的工作方式。有人能帮我吗?
虽然 UDP 在协议级别是无连接的,但 UDP套接字仍然可以“连接到” - 这不会生成任何消息,但仍然具有在操作系统级别将套接字绑定到特定远程地址:端口的相同效果。
一旦调用了 connect(),调用 recv() 将仅将数据报从指定的发送者传送到程序,反之亦然,程序也可以在该套接字上调用 send() 而不指定接收者(与在未连接的套接字上使用 recvfrom() / sendto() 相反)。
在接收到第一个数据包时,您的实现
nc
将调用 connect() 来“锁定”该特定流,而发送端将创建一个新的套接字,因此每次重新启动时都会选择不同的源端口号。为了实现您的目标,您可能需要
socat udp-recvfrom:[...]
(不是 udp-recv),尽管您可以尝试nc -u -p 12345 <dst> <port>
强制每个发送方进程每次都绑定到同一个本地(源)端口。