我需要立即关闭具有未发送数据的UDP套接字。 TCP套接字有SO_LINGER参数,但我没有找到UDP的任何内容。 它在Windows上。
提前致谢。
更新0:
我给出了这个问题的背景。我有应用程序第一个线程打开/绑定/关闭套接字,第二个线程发送数据报到它。 在某些情况下,关闭套接字(errorcode = 0)后,绑定函数将返回错误代码10048“已在使用的地址”。我在close()执行端口仍然使用后发现(通过netstat命令)。也许我问的是不正确的问题,这种行为的原因是别的吗?
答案 0 :(得分:1)
对于所有应用程序,一旦您的send()
返回,数据包就会被“发送”。 TCP中没有发送缓冲区,您无法控制NIC数据包队列。正常close()
就是您所需要的。
@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中有任何这样的功能可能会导致这种情况。