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

来源:互联网 发布:怎么复制淘宝商品链接 编辑:程序博客网 时间:2024/06/03 09:10


       我们在编写网络通信程序的时候,不论作为服务端还是客户端,常常需要确保实时检测与对方的连接状态,调用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 0
原创粉丝点击