判断SOCKET是否还连接

1. 用read函数来判断

 读到长度0不能断定是已经断开.除非是-1,才代表输入流已经被关闭,说名socket已经close,而且关键在于你怎么读,实际上应该是一个单独的线程一直在读,因为你无法预先知道能不能一次将发过来的包读完,也无法知道一次是不是读完整了包,所以线称一直循环在读并且一直在解包.这样即能知道什么时候server断,也完成了消息的解读


// 判断是否连接
char ch = 'A';
if (read(g_sockfd, &ch, 1)<=0)
{
if (connect(g_sockfd,(struct sockaddr*)&g_serv_addr, sizeof(g_serv_addr) ) == 0)
        {
                  ServiceLog.write_log("[NotifyDAU]:connect to DAU  success.");
        }
         else
         {
                   ServiceLog.write_log("[NotifyDAU]:can't connect to DAU ");
                   return;
         }
}

用try{}catch{}是比较合适。

 当他是连着的,当进行通讯时发生异常后就知道了.

当你不断的read的时候,server断,exception就catch到了。

 

2. 心跳包

可以在Client设一个定时器,每隔一段时间发一条消息给服务器,看能不能收到服务器的响应。

心跳包就是定时发包,没回应就判断断开。

 

3. getsockopt

(2014更新说明)最初以为使用这个方式很次,在最近一个项目需要用到getsockopt才又仔细去深入研究,发现当初自己的使用是存在问题的所以造成结果不准确。

使用getsockopt时,实际上是检查端口状态来间接判断连接是否成功,打个比方,有种情况你没用recv而是做send操作,这个时候如果你老是检查read状态是你会发现一直是失败的。根据状态来判断连接,使用好你要判断端口的哪个状态(以前我的问题就是出在这里)

bool Connected(const SOCKET socketfd)
{
	if(socketfd == INVALID_SOCKET) return false;

	struct timeval timeout;
	timeout.tv_sec = 0;
	timeout.tv_usec = 0;
	fd_set fdwrite;
	fd_set fdread;
	FD_ZERO(&fdwrite);
	FD_ZERO(&fdread);
	FD_SET(socketfd,&fdwrite);
	FD_SET(socketfd,&fdread);
	int ret = select(socketfd+1, &fdread, &fdwrite, NULL, &timeout);
	if(ret == -1)
		return false;

	if(ret > 0)
	{
		if(FD_ISSET(socketfd,&fdread))
			return false;
		else if(FD_ISSET(socketfd,&fdwrite))
		{
			int err = 0;
			int len = sizeof(err);
			int result = getsockopt(socketfd,SOL_SOCKET,SO_ERROR,(char*)&err,&len);
			if(result < 0 || err != 0)
				return false;
			return true;
		}
	}
	return false;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值