我有一个UDP套接字调用sendto()
。有时(并非总是)它会阻止我的应用程序约2.5秒。当我检查sendto()
来电的返回值时,我会SOCKET_ERROR(-1)
而WSAGetLastError()
会返回WSAETIMEDOUT(10060)
为什么UDP套接字超时?在什么情况下sendto()
会成为阻止电话?
答案 0 :(得分:3)
为什么UDP套接字会超时?
如果套接字在阻塞模式(默认模式)下运行,并且分配了发送超时,则会发生这种情况。
在什么情况下sendto()会成为阻止呼叫?
默认情况下,套接字以阻塞模式创建。如果需要,您必须明确请求非阻塞行为。
在阻塞模式下,如果内核缓冲区填满或者WinSock在完成发送之前必须等待网络事件,UDP套接字可能会阻塞。这是记录在案的行为:
当发出阻止的Winsock调用(例如sendto)时,Winsock可能需要等待网络事件才能完成调用。 Winsock在这种情况下执行可警告的等待,可以通过在同一线程上安排的异步过程调用(APC)来中断。在APC内发出另一个阻塞Winsock调用,该调用在同一个线程上中断正在进行的阻塞Winsock调用将导致未定义的行为,并且Winsock客户端绝不能尝试。
...
如果传输系统中没有可用的缓冲区空间来保存要传输的数据,则sendto将阻止,除非套接字已置于非阻塞模式。在非阻塞,面向流的套接字上,写入的字节数可以在1和请求的长度之间,具体取决于客户端和服务器系统上的缓冲区可用性。 select,WSAAsyncSelect或WSAEventSelect函数可用于确定何时可以发送更多数据。