GetQueuedCompletionStatus 延迟
我编写了基于 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
}
为什么会发生这种情况?我需要立即了解连接关闭才能连接到备份服务器(负载不是那么重 - 因此会发生断开连接)。
I have written complex library for managing network communication based on iocp mechanism. Problem is that when server closes the connection by calling API method closesocket() this information is sometimes transmitted to client delayed by seconds or even minutes. My code for detecting connection closure looks like this (simplified):
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
}
Why is this happening? I need to know about connection closure immediately to be able to connect to backup server (not so heavily loaded - disconnect is happening because of this).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你如何关闭连接?
如果您只是调用
closesocket()
,那么您将启动一个关闭序列,该序列将尝试确保当前待处理的所有数据都将到达目的地。这可能需要一些时间,尤其是在网络连接过载、数据报丢失并且发生 TCP 重传的情况下。如果您想立即关闭连接并丢失任何挂起的数据,请将 linger 设置为 0,然后关闭套接字。这将在连接上发出 RST,并且您会更快地获得该结果。
How are you closing the connection?
If you're just calling
closesocket()
then you are initiating a shutdown sequence which will attempt to ensure that all data that is currently pending will reach the destination. This can take time, especially if the network connection has been overloaded and datagrams have been lost and TCP retransmission is occurring.If you want to close the connection straight away, and lose any pending data, then set linger to 0 and then close the socket. This will issue an RST on the connection and you'll get that much quicker.
我尝试按照 Len 所写的那样尝试使用 linger 参数,但这没有帮助。在 closesocket() 之前添加 shutdown() 函数的调用对我有帮助。在分析到达客户端网络接口的数据包(使用 WireShark)后,我发现 RST 数据包被 FIN 数据包替换。奇怪的是,RST 数据包没有延迟。因此操作系统知道连接已关闭,但由于某种未知原因,该信息传输到应用程序层的时间非常延迟。我测得延迟在 10 秒到 4 分钟之间。
I tried to experiment with linger parameter as Len wrote but this did not help. Adding call of shutdown() function just before closesocket() helped me. After analyzing packets reaching network interface on client (with WireShark) I have found that RST packet was replaced by FIN packet. Curiously that RST packet was not delayed. So operating system knew that connection was closed but by some unknown reason this information was transferred to application layer very delayed. I measured delays between 10 seconds and 4 minutes.