Chinaunix首页 | 论坛 | 博客
  • 博客访问: 57769
  • 博文数量: 16
  • 博客积分: 70
  • 博客等级: 民兵
  • 技术积分: 66
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-07 09:54
文章分类
文章存档

2015年(11)

2014年(1)

2013年(2)

2012年(2)

我的朋友

分类: C/C++

2014-05-23 16:55:06

原文地址:http://www.cppblog.com/prayer/archive/2009/04/14/79900.aspx

最近在做一个服务器端程序,C/S结构。功能方面比较简单就是client端与server端建立连接,然后发送消息给server。我在server端会使用专门的线程处理一条socket连接。这就涉及到一个问题,如果socket连接断开(异常,正常)后,我如何才能感知到?server端这边是绝对被动的,sever端不能主动断开连接。也没有连接链路维持包之类的。client端发送数据的时间也是不定的。在socket连接断开后, server要能够感知到并释放资源。
这个问题在思考测试,询问同事之后,找到了一个方法,可以做到这一点。
当使用 select()函数测试一个socket是否可读时,如果select()函数返回值为1,且使用recv()函数读取的数据长度为0 时,就说明该socket已经断开。
为了更好的判定socket是否断开,我判断当recv()返回值小于等于0时,socket连接断开。但是还需要判断 errno是否等于 EINTR 。如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的,socket连接还是正常的,不应close掉socket连接。

PS:对于堵塞socket的recv函数会在以下三种情况下返回:
(1)recv到数据时,会返回。
(2)在整个程序接收到信号时,返回-1。errno = EINTR。//在程序的起始阶段,屏蔽掉信号的除外。部分信号还是屏蔽不掉的。
(3)socket出现问题时,返回-1.具体错误码看 man recv()
(4)一定要看 man 说明,很详细,很有帮助。
这种方法经过长时间测试后,是有效的。

另一种方法:
我的方法不一样,我用getsockopt来判断,还是蛮准确的 
int SocketConnected(int sock) 

    if(sock<=0) 
    return 0; 
    struct tcp_info info; 
    int len=sizeof(info); 
    getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len); 
    if((info.tcpi_state==TCP_ESTABLISHED))  
        //myprintf("socket connected\n"); 
        return 1; 
    } else 
        //myprintf("socket disconnected\n"); 
        return 0; 
    } 
}

阅读(1978) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~