C++ GetQueuedCompletionStatus延迟
我已经编写了基于iocp机制管理网络通信的复杂库。问题是,当服务器通过调用API方法closesocket()关闭连接时,此信息有时会延迟几秒钟甚至几分钟传输到客户端。我检测连接关闭的代码如下(简化):C++ GetQueuedCompletionStatus延迟,c++,sockets,iocp,C++,Sockets,Iocp,我已经编写了基于iocp机制管理网络通信的复杂库。问题是,当服务器通过调用API方法closesocket()关闭连接时,此信息有时会延迟几秒钟甚至几分钟传输到客户端。我检测连接关闭的代码如下(简化): 为什么会这样?我需要立即了解连接关闭的情况,以便能够连接到备份服务器(负载不太重-因此正在断开连接)。如何关闭连接 如果您只是调用closesocket(),那么您将启动一个关机序列,该序列将尝试确保当前挂起的所有数据都将到达目标。这可能需要时间,尤其是在网络连接过载、数据报丢失以及TCP重新传
为什么会这样?我需要立即了解连接关闭的情况,以便能够连接到备份服务器(负载不太重-因此正在断开连接)。如何关闭连接 如果您只是调用
closesocket()
,那么您将启动一个关机序列,该序列将尝试确保当前挂起的所有数据都将到达目标。这可能需要时间,尤其是在网络连接过载、数据报丢失以及TCP重新传输发生时
如果要立即关闭连接,并丢失所有挂起的数据,请将linger设置为0,然后关闭套接字。这将在连接上发出RST,您将获得更快的速度。我尝试使用Len编写的linger参数进行实验,但这没有帮助。在closesocket()之前添加shutdown()函数的调用对我有帮助。在分析到达客户端网络接口的数据包(使用WireShark)后,我发现RST数据包被FIN数据包取代。奇怪的是,RST数据包没有延迟。所以操作系统知道连接已关闭,但由于某种未知原因,该信息传输到应用层的时间非常延迟。我测量了10秒到4分钟之间的延迟。与您的问题没有直接关系,但您应该检查重叠的值以及处理程序中的返回代码。重叠时==NULL表示GetQueuedCompletionStatus失败,重叠时!=NULL表示I/O请求失败。
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
}