1

背景:我正在使用 CreateIoCompletionPort、WSASend/Recv 和 GetQueuedCompletionStatus 在我的服务器上执行重叠套接字 io。对于流控制,当发送到客户端时,我只允许在所有挂起的 OVERLAP 都从 IOCP 弹出时调用几个 WSASend()。

问题:最近,有一些情况是 OVERLAP 没有返回到 IOCP。调用 GetQueuedCompletionStatus 的线程没有得到它们,它们保留在我的本地挂起队列中。我已经验证客户端确实从套接字接收数据并且套接字已连接。进行 WSASend() 调用时没有返回错误。没有外部刺激,重叠只是“永远不会”回来,如下所示:

  1. 从客户端或服务器断开套接字,立即允许 GetQueuedCompletionStatus 线程检索 OVERLAP
  2. 在所有 OVERLAP 突然从队列中弹出之前,有时需要多次调用 WSASend()。

问题:有人见过这种行为吗?关于造成这种情况的任何想法?

谢谢,杰弗里

4

1 回答 1

4

WSASend()如果 TCP 窗口已满,则可能无法及时完成。在这种情况下,堆栈不能再发送任何数据,因此您的WSASend()等待和完成不会发生,直到 TCP 堆栈可以发送更多数据。

如果您碰巧在客户端和服务器之间有一个协议,该协议本身没有内置流量控制,并且您自己没有根据写入完成进行任何流量控制,并且只是以服务器可以发送的速度发送数据,那么您可能会达到网络或您的客户端无法跟上并且 TCP 流控制启动的地步(当 TCP 窗口已满时)。如果您继续通过附加调用异步触发数据,WSASend()那么最终您将在机器上的所有非分页内存中咀嚼,此时所有的赌注都被关闭(驱动程序可能导致框到蓝屏)。

因此,总而言之,重叠套接字写入的完成可能而且有时需要比您预期的更长的时间才能返回。在您的示例中,我希望您在关闭套接字时获得的完成都是失败的?

我在我的博客上谈了更多;此处: http: //www.lenholgate.com/blog/2008/07/write-completion-flow-control.html此处:http ://www.serverframework.com/asynchronousevents/2011/06/tcp-flow-控制和异步writes.html

于 2009-12-02T13:53:27.277 回答