如何关闭Winsock UDP套接字?

时间:2012-07-24 16:06:05

标签: windows sockets udp

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

提前致谢。

更新0:

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

3 个答案:

答案 0 :(得分:1)

对于所有应用程序,一旦您的send()返回,数据包就会被“发送”。 TCP中没有发送缓冲区,您无法控制NIC数据包队列。正常close()就是您所需要的。

编辑0:

@EJP,这是UNP给你的报价(第2.11节“UDP输出”):

  

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

这就是我在回答中的意思 - 你无法控制发送缓冲区 - 所以“为了所有应用目的”它不存在。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我也遇到了Windows UDP套接字的这个问题。经过几个小时的尝试,我终于发现我的问题是我在主线程上调用socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)来创建套接字,在工作线程上调用bind(...)recvfrom(),然后关闭工作线程我在主线程上调用了closesocket(...)。没有任何函数返回错误但是由于某种原因,这样做会使UDP地址/端口组合在使用中(因此将来调用bind()会触发错误10048 WSAEADDRINUSE并且netstat -abot -p UDP也会显示该端口仍在使用中,直到整个申请已经结束)。解决方案是将socket(...)closesocket(...)调用移动到工作线程中。

除了上述情况之类的奇怪问题之外,通常无法在调用closesocket()之后将UDP服务器套接字保持打开状态。 Microsoft explains没有与UDP套接字保持连接,也不需要调用shutdown()或任何其他功能。通常,在调用closesocket()之后TCP套接字保持打开的原因是它没有正常断开连接并且它在TCP_WAIT状态下等待大约4分钟,以便在实际可能的其他数据进入之前关闭。在上面的例子中,netstat显示UDP套接字永远不会关闭,直到应用程序关闭,即使我等了30多分钟。

如果您正在使用像.NET框架这样的winsock包装器,我还会读到一些功能,例如设置异步回调可以让UDP套接字打开,如果您不清理回调正确,但我不认为win32 winsock API中有任何这样的功能可能会导致这种情况。

相关问题