1

我需要立即关闭未发送数据的 UDP 套接字。TCP 套接字有 SO_LINGER 参数,但我没有找到任何关于 UDP 的信息。它在 Windows 上。

提前致谢。

更新0:

我给出了这个问题的背景。我有应用程序第一个线程打开/绑定/关闭套接字,第二个线程向它发送数据报。在某些情况下,关闭套接字 (errorcode = 0) 后,bind 函数会返回错误代码 10048“地址已在使用中”。我发现 close() 执行端口后仍然使用(通过 netstat 命令)。也许我问了不正确的问题,而这种行为的原因是别的?

4

3 回答 3

1

出于所有申请目的,一旦您send()返回,该数据包将被“发送”。没有像 TCP 那样的发送缓冲区,而且您无法控制 NIC 数据包队列。正常close()就是你所需要的。

编辑0:

@EJP,这是来自 UNP 的引述(第 2.11 节“UDP 输出”):

这一次,我们将套接字发送缓冲区显示为虚线框,因为它实际上并不存在。一个 UDP 套接字有一个发送缓冲区大小(我们可以用 SO_SNDBUF套接字选项改变它,第 7.5 节),但这只是可以写入套接字的最大 UDP 数据报的上限。如果应用程序写入的数据报大于套接字发送缓冲区大小,EMSGSIZE则返回。由于 UDP 不可靠,它不需要 tp 保留应用程序数据的副本,也不需要实际的发送缓冲区。(应用程序数据通常在向下传递协议栈时被复制到某种形式的内核缓冲区中,但在数据传输后,该副本会被数据链路层丢弃。)

这就是我在回答中的意思-您无法控制发送缓冲区-,因此“出于所有应用程序目的”它不存在。

于 2012-07-24T16:23:59.870 回答
0

我在 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中有任何可能导致这种情况的功能。

于 2014-09-30T20:41:49.267 回答
0

关闭它。与 TCP 不同,UDP 中没有任何内容表明将发送待处理的数据。

于 2012-07-25T07:28:16.610 回答