封装Linux下网络连通性检测函数



       我们在编写网络通信程序的时候,不论作为服务端还是客户端,常常需要确保实时检测与对方的连接状态,调用select函数监控文件描述符套接字)的连接状态是最普遍的方法,但是当遇到对方断电或者网络线路突然断开的情况,select函数将接收不到来自对方的断开消息,所以维护着这一连接的文件描述符(套接字)已经没有存在的意义,这个时候往该文件描述符(套接字)内写内容依然不会返回错误,read也会堵塞着并不返回错误。因此也无法断定该套接字是否还处于连接状态,我们可以通过开启TCP的keepAlive选项来让TCP连接自身维护自己的连接状态,详见《Linux下回收异常断开的TCP连接》,但是倘若要及时检测网络连通性,不得不频繁地发心跳包,势必会影响通信带宽,不是很理想。    

另外一种办法是在select超时或者指定时间去connect一次对方,因为connect涉及到传输层跟应用层,为了消耗更少的带宽,减少对于应用层的干扰,可以考虑调用Ping命令走ICMP协议封装Linux下网络连通性检测函数。下面是我用C语言封装的一个检测实例。

#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int checkConnect(char *dst, int cnt)
{
    int i = 0;
    FILE *stream;
    char recvBuf[16] = {0};
    char cmdBuf[256] = {0};

    if (NULL == dst || cnt <= 0)
        return -1;

    sprintf(cmdBuf, "ping %s -c %d -i 0.2 | grep time= | wc -l", dst, cnt);
    stream = popen(cmdBuf, "r");
    fread(recvBuf, sizeof(char), sizeof(recvBuf)-1, stream);
    pclose(stream);

    if (atoi(recvBuf) > 0)
    return 0;

    return -1;
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        printf("Please set the arguments as follow:\n");
        printf("%s <destination> <count>\n", argv[0]);
        return -1;
    }

    if (checkConnect(argv[1], atoi(argv[2])))
        printf("Network is not up to %s\n", argv[1]);
    else
        printf("Network is up to %s\n", argv[1]);

    return 0;
}

       上面提到的connect跟Ping封装虽然比keepLive更灵活,但仍然存在不足,对于服务器来说很难实现,因为通常客户端都处于内网,外网的服务器无法主动connect到内网客户端,所以也不够通用,只能在应用层上下功夫了,可以考虑通信双方协商一个专门用于检测连接状态的命令字,其中一方收到来自另一方的网络检测命令字后,回应一个确认命令字告诉对方自己当前在线,如果一方发送检测命令字后得不到回应,则作对方掉线处理,回收套接字并释放相关资源。

http://www.cpplive.com/html/1527.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值