GetQueuedCompletionStatus延迟了

时间:2011-04-29 10:07:39

标签: c++ sockets iocp

我编写了基于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
}

为什么会这样?我需要立即知道连接关闭以便能够连接到备份服务器(没有那么多负载 - 因此发生断开连接)。

2 个答案:

答案 0 :(得分:1)

你是如何关闭连接的?

如果您只是致电closesocket(),那么您正在启动关机序列,该序列将尝试确保当前待处理的所有数据都将到达目的地。这可能需要一些时间,特别是如果网络连接已经过载并且数据报丢失并且正在进行TCP重传。

如果要立即关闭连接,并丢失任何待处理数据,请将“逗号”设置为0,然后关闭套接字。这将在连接上发出一个RST,你会更快。

答案 1 :(得分:0)

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