GetQueuedCompletionStatus delayed

GetQueuedCompletionStatus delayed

本文关键字:delayed GetQueuedCompletionStatus      更新时间:2023-10-16

我写了一个复杂的库来管理基于iocp机制的网络通信。问题是,当服务器通过调用API方法closesocket()关闭连接时,该信息有时会延迟几秒甚至几分钟传输到客户端。我检测连接关闭的代码看起来像这样(简化):

ok = GetQueuedCompletionStatus(completion_port, &io_size, (PULONG_PTR)&context, &overlapped, 40);
if (!ok) {
   // something went broken
  DWORD err = GetLastError();
  if (err == ERROR_CONNECTION_REFUSED) {
         // connection failed
  } else if (err == ERROR_SEM_TIMEOUT) {
        // connection timeout
  } else if (err == ERROR_NETNAME_DELETED) {
        // connection closure - point of interest
  } else if (err != WAIT_TIMEOUT) {
        // unknown error
  }
} else {
    // process incomming or outgoing data
}

为什么会发生这种情况?我需要知道连接关闭立即能够连接到备份服务器(不是如此沉重的负载-断开连接正在发生,因为这个)。

如何关闭连接?

如果你只是调用closesocket(),那么你正在启动一个关闭序列,该序列将尝试确保当前挂起的所有数据将到达目的地。这可能需要一些时间,特别是在网络连接过载、数据报丢失和TCP重传发生的情况下。

如果您想要立即关闭连接,并丢失任何挂起的数据,那么将linger设置为0,然后关闭套接字。这将在连接上发出RST,您将获得更快的速度。

我试着像Len写的那样尝试使用逗留参数,但这没有帮助。在closeocket()之前添加shutdown()函数调用对我很有帮助。在分析到达客户端网口的报文后(用WireShark),我发现RST报文被FIN报文代替了。奇怪的是,RST报文没有被延迟。因此,操作系统知道连接已关闭,但由于某些未知的原因,该信息传输到应用层非常延迟。我测量的延迟在10秒到4分钟之间。