封装Linux下网络连通性检测函数
2015-06-11 14:14
447 查看
我们在编写网络通信程序的时候,不论作为服务端还是客户端,常常需要确保实时检测与对方的连接状态,调用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
我们在编写网络通信程序的时候,不论作为服务端还是客户端,常常需要确保实时检测与对方的连接状态,调用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
相关文章推荐
- 5 个用于在 Linux 终端中查找域名 IP 地址的命令
- 如何让 Ping 的输出更简单易读
- .net实现ping的实例代码
- Ping服务的php实现方法,让网站快速被收录
- IP策略实现服务器禁止Ping
- 服务器禁止被ping的设置方法(图文)
- perl ping检测功能脚本代码
- javascript模拟的Ping效果代码 (Web Ping)
- 纯Javascript实现ping功能的方法
- php实现的ping端口函数实例
- python在windows下实现ping操作并接收返回信息的方法
- python使用xmlrpclib模块实现对百度google的ping功能
- 配置win2008防火墙 允许被Ping的设置方法
- Python实现检测服务器是否可以ping通的2种方法
- Mybatis破MySql8小时断线问题
- 大家来参考,是否本博客需要增加又拍云存储呢?
- 物理机ping不同虚拟机上microsoft server 2008
- ping命令两种返回信息的区别
- linux 的ping 命令
- Win32_PingStatus vs [System.Net.NetworkInformation.Ping] vs Ping.exe