UDP 未连接套接字发送失败,直到它收到第一个数据报
UDP unconnected socket sending fails until it receives 1st datagram
我正在使用 Windows 7 中的 Winsock class CAsyncSocket 创建一个 UDP 聊天程序。它只是打开一个未连接的 UDP 套接字,并允许将文本字符串发送到另一台计算机以及 运行 聊天程序。我发现当我的聊天程序在两台计算机上运行时,以太网 NIC 通过交叉电缆连接(因此没有其他网络流量),无论哪台计算机首先尝试传输,直到从另一台计算机发送第一个数据报后,它才会成功。在下面的屏幕截图中,计算机 #1 尝试发送 "test" 三次,而计算机 #2 未收到。然后计算机 #2 发送 "hello" 并被 #1 接收。然后计算机 #1 再次发送 "test" 并且这次它被接收了。尽管来自 #1 的 "test" 的三个初始传输似乎没有通过,但它们显然做了一些事情,因为如果来自 #2 的 "hello" 在来自 #1 的 "test" 消息之前发送,那么 "hello" 消息是丢失的消息。
计算机 #1
计算机 #2
每台计算机成功发送数据报后,所有后续数据报都可以毫无问题地发送和接收。如果我仅在一侧关闭并重新打开套接字 [重置本地端口],那么每台计算机仍然可以成功发送和接收。如果我 [重置本地端口] 两台计算机,那么在大多数情况下,第一个发送的计算机会遇到同样的问题,但并非总是如此。有时甚至在 [重置本地端口] 之后发送和接收仍然有效。
创建未连接套接字的调用是
Create(i_LocalPort, SOCK_DGRAM, FD_READ, m_LocalSockAddrIn.AddrStr());
然后
CAsyncSocket::SendTo()
发送数据报。寻找有关这里发生的事情的一些提示。
更新信息:使用 Wireshark 查看丢失的数据包似乎是用适当的源地址和目标地址发送的,但目标没有接收到它们。
问题是由 Windows 防火墙引起的。我关闭了两台计算机上的防火墙问题就消失了。通常 Windows 在阻止访问时会弹出一个对话框,但其中一台计算机已禁用 "Notify me when Windows Firewall blocks a new program" 所以没有对话框消息。它只是默默地丢弃了数据报。我希望它在发送消息后允许数据报通过的原因是它有一个例外,允许从程序发送到的端口接收。所以在发送到另一个端口后,就可以从它接收。
我正在使用 Windows 7 中的 Winsock class CAsyncSocket 创建一个 UDP 聊天程序。它只是打开一个未连接的 UDP 套接字,并允许将文本字符串发送到另一台计算机以及 运行 聊天程序。我发现当我的聊天程序在两台计算机上运行时,以太网 NIC 通过交叉电缆连接(因此没有其他网络流量),无论哪台计算机首先尝试传输,直到从另一台计算机发送第一个数据报后,它才会成功。在下面的屏幕截图中,计算机 #1 尝试发送 "test" 三次,而计算机 #2 未收到。然后计算机 #2 发送 "hello" 并被 #1 接收。然后计算机 #1 再次发送 "test" 并且这次它被接收了。尽管来自 #1 的 "test" 的三个初始传输似乎没有通过,但它们显然做了一些事情,因为如果来自 #2 的 "hello" 在来自 #1 的 "test" 消息之前发送,那么 "hello" 消息是丢失的消息。
计算机 #1
计算机 #2
每台计算机成功发送数据报后,所有后续数据报都可以毫无问题地发送和接收。如果我仅在一侧关闭并重新打开套接字 [重置本地端口],那么每台计算机仍然可以成功发送和接收。如果我 [重置本地端口] 两台计算机,那么在大多数情况下,第一个发送的计算机会遇到同样的问题,但并非总是如此。有时甚至在 [重置本地端口] 之后发送和接收仍然有效。 创建未连接套接字的调用是
Create(i_LocalPort, SOCK_DGRAM, FD_READ, m_LocalSockAddrIn.AddrStr());
然后
CAsyncSocket::SendTo()
发送数据报。寻找有关这里发生的事情的一些提示。
更新信息:使用 Wireshark 查看丢失的数据包似乎是用适当的源地址和目标地址发送的,但目标没有接收到它们。
问题是由 Windows 防火墙引起的。我关闭了两台计算机上的防火墙问题就消失了。通常 Windows 在阻止访问时会弹出一个对话框,但其中一台计算机已禁用 "Notify me when Windows Firewall blocks a new program" 所以没有对话框消息。它只是默默地丢弃了数据报。我希望它在发送消息后允许数据报通过的原因是它有一个例外,允许从程序发送到的端口接收。所以在发送到另一个端口后,就可以从它接收。