网络编程-基于IOCP的服务器中使用TCP连接时如何知道客户端已经异常断开?

发布于 2017-03-12 04:09:24 字数 99 浏览 1597 评论 5

基于IOCP的服务器,经常会发生客户端断开连接。由于网络经常出现一些异常情况,比如一方的机器突然断电,这时要过很久后才能得知该TCP链接已经断掉。如何才能很快知道该TCP链接已经断了?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

清晨说ぺ晚安 2017-09-15 19:11:10

GetQueuedCompletionStatus不能得出网络是否异常了,比如客户端拔网线,比如突然重启,这些是无法捕获的。这是由于TCP协议本身的问题,其实细想一下,客户端还没有把数据发送缓冲区时系统就崩溃了,这种情况下肯定无法捕获的,只能通过应用协议来判断了。常用的解决方法三种:

定时心跳包,超时没收到回应,就认为客户端就是断开了。
通过SO_KEEPALIVE来判断,默认是2小时进行一次检测,自己也可以设置检测间隔,但会影响其它系统所有正在使用的Socket,慎用
通过SIO_KEEPALIVE_VALS,该选项不同于SO_KEEPALIVE 机制的就是它是针对单个连接的,对系统其他的Sokcet并不影响。

想挽留 2017-09-14 07:56:46

用户层的心跳包检测机制必不可少,客户端端定时发送用户层心跳包,服务器端针对每个已连接套接字记录最后一次收到心跳包的时间,同时开启线程定时检测:超过XX秒还未收到心跳包的套接字,kill掉,释放占用的上下文及收发缓冲区资源。

晚风撩人 2017-08-29 13:19:49

一般都是定时发送消息吧,即心跳包,不知道还有其他什么方法不。关注。

瑾兮 2017-06-28 16:42:36

BOOL r = ::GetQueuedCompletionStatus(hCompletionPort, &dwBytesTransferred, (LPDWORD)&hCompletionSocket, (LPWSAOVERLAPPED *) &lpOvlpEx, INFINITE);
if (hCompletionSocket== INVALID_SOCKET || lpOvlpEx == NULL)
{
Sleep(10);
continue;
}

if (!r)
{
proxy->SafeClose(lpOvlpEx);
TRACE("GetQueuedCompletionStatus error! %dn",hSocket);
continue;
}
else if (dwBytesTransferred ==0)
{
proxy->SafeClose(lpOvlpEx);
TRACE(".....................%d..........closed & freed........n",hSocket);
continue;
}
}

上面的GetQueuedCompletionStatus是接收IOCP通知的主要函数,通过dwBytesTransferred、hCompletionSocket、lpOvlpEx以及返回值r即可判断出客户端是否关闭。

晚风撩人 2017-06-04 03:08:44

一般都是客户端发送心跳ping包,如果 ping 包没有回应,则客户端认为掉线了,对于服务器来说,如果完成端口没有反应了,则会调用 GetQueuedCompletionStatus 函数来判断

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文