【问题标题】:UDP socket gives error WSAETIMEDOUTUDP 套接字给出错误 WSAETIMEDOUT
【发布时间】:2015-09-18 20:07:15
【问题描述】:

我已致电sendto() 获取 UDP 套接字。有时(并非总是)它会阻止我的应用程序约 2.5 秒。当我检查sendto() 调用的返回值时,我得到SOCKET_ERROR(-1)WSAGetLastError() 返回WSAETIMEDOUT(10060)

为什么 UDP 套接字会超时?在什么情况下sendto()会是阻塞调用?

【问题讨论】:

标签: sockets udp winsock2


【解决方案1】:

为什么 UDP 套接字会超时?

如果套接字以阻塞模式(默认模式)运行,并且分配了发送超时,则可能发生这种情况。

在什么情况下 sendto() 会成为阻塞调用?

默认情况下,套接字以阻塞模式创建。如果需要,您必须明确请求非阻塞行为。

在阻塞模式下,如果内核缓冲区已满或 WinSock 必须等待网络事件才能完成发送,则 UDP 套接字会阻塞。这是记录在案的行为:

sendto() function

在发出诸如 sendto 之类的阻塞 Winsock 调用时,Winsock 可能需要等待网络事件才能完成调用。 Winsock 在这种情况下会执行警报等待,该等待可能会被安排在同一线程上的异步过程调用 (APC) 中断。在 APC 中发出另一个阻塞 Winsock 调用中断了同一线程上正在进行的阻塞 Winsock 调用将导致未定义的行为,并且 Winsock 客户端绝不能尝试。

...

如果传输系统中没有可用的缓冲区空间来保存要传输的数据,则 sendto 将阻塞,除非套接字已置于非阻塞模式。在非阻塞、面向流的套接字上,写入的字节数可以在 1 和请求的长度之间,这取决于客户端和服务器系统上的缓冲区可用性。 select、WSAAsyncSelect 或 WSAEventSelect 函数可用于确定何时可以发送更多数据。

【讨论】:

  • 也许我对套接字的工作方式有错误的想法,但是由于 udp 不能保证消息会到达目的地,那么什么超时会导致这个阻塞?套接字是否在等待接收端的 ack?
  • 没有。阻塞的最可能原因是网络拥塞。数据在代码中发送的速度比套接字传输它的速度要快,因此传出缓冲区会填满并阻塞。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多