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分钟之间。