我在 Windows UDP 套接字上也遇到了这个问题。经过数小时的尝试,我终于发现我的问题是我socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
在主线程上调用以创建套接字,在工作线程上调用bind(...)
和recvfrom()
,然后在关闭工作线程后我closesocket(...)
在主线程上调用。没有一个函数返回错误,但出于某种原因,这样做会使 UDP 地址/端口组合处于使用状态(因此将来对 bind() 的调用会触发错误 10048 WSAEADDRINUSE 并且netstat -abot -p UDP
还会显示端口仍在使用中,直到整个应用程序关闭)。解决方案是移动socket(...)
并closesocket(...)
调用工作线程。
除了上述情况的奇怪问题外,通常情况下,UDP 服务器套接字在调用它后无法保持打开状态closesocket()
。 微软解释说,没有与 UDP 套接字保持连接,也不需要调用shutdown()
或任何其他函数。通常 TCP 套接字在调用后保持打开状态的原因closesocket()
是它没有正常断开连接,并且它在 TCP_WAIT 状态下等待大约 4 分钟,以便在实际关闭之前可能有额外的数据进入。在上述情况下,netstat 显示 UDP 套接字在应用程序关闭之前从未关闭,即使我等待了 30 多分钟。
如果您使用 .NET 框架之类的 winsock 包装器,我还阅读了一些功能,例如设置异步回调可以使 UDP 套接字绑定打开,如果您没有正确清理回调,但我没有认为win32 winsock API中有任何可能导致这种情况的功能。