您的位置:首页 > 理论基础 > 计算机网络

iocp网络通信之如何判断客户端连接断开

2013-11-19 22:38 423 查看
BOOL r = ::GetQueuedCompletionStatus(hCompletionPort, &dwBytesTransferred, (LPDWORD)&hCompletionSocket, (LPWSAOVERL	APPED *) &lpOvlpEx, INFINITE);
if (hCompletionSocket== INVALID_SOCKET || lpOvlpEx == NULL)
{
Sleep(10);
continue;
}

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


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

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

定时心跳包,超时没收到回应,就认为客户端就是断开了。
通过SO_KEEPALIVE来判断,默认是2小时进行一次检测,自己也可以设置检测间隔,但会影响其它系统所有正在使用的Socket,慎用
通过SIO_KEEPALIVE_VALS,该选项不同于SO_KEEPALIVE 机制的就是它是针对单个连接的,对系统其他的Sokcet并不影响。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: