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

解析GetQueuedCompletionStatus函数及网络异常处理
本文详细解读了使用GetQueuedCompletionStatus函数接收IOCP通知的原理,以及如何通过定时心跳包、SO_KEEPALIVE和SIO_KEEPALIVE_VALS等方法来判断客户端是否关闭或网络是否异常。重点介绍了在网络不稳定或客户端意外断开连接时的应对策略。

 

	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协议本身的问题,其实细想一下,客户端还没有把数据发送缓冲区时系统就崩溃了,这种情况下肯定无法捕获的,只能通过应用协议来判断了。常用的解决方法三种:

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值