我编写了基于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
}
为什么会这样?我需要立即知道连接关闭以便能够连接到备份服务器(没有那么多负载 - 因此发生断开连接)。
答案 0 :(得分:1)
你是如何关闭连接的?
如果您只是致电closesocket()
,那么您正在启动关机序列,该序列将尝试确保当前待处理的所有数据都将到达目的地。这可能需要一些时间,特别是如果网络连接已经过载并且数据报丢失并且正在进行TCP重传。
如果要立即关闭连接,并丢失任何待处理数据,请将“逗号”设置为0,然后关闭套接字。这将在连接上发出一个RST,你会更快。
答案 1 :(得分:0)
我试着像Len写的那样尝试使用linger参数,但这并没有帮助。在closesocket()之前添加对shutdown()函数的调用帮助了我。在分析到达客户端上的网络接口的数据包(使用WireShark)后,我发现RST数据包被FIN数据包替换。奇怪的是,RST数据包没有延迟。因此,操作系统知道连接已关闭,但由于某些未知原因,此信息被非常延迟地传输到应用程序层。我测量了10秒到4分钟之间的延迟。