精选文章

Android下使用TCPDUMP抓包Wireshark分析数据 如果想分析Android下某个APP的网络数据交互,需要在Android手机上抓包,最常用的抓包工具非tcpdump莫属,用tcpdump生成Wireshark识别的pcap文件,然后将pcap文件下载到电脑上,用电脑上的Wireshark加载pcap文件,通过Wireshark分析tcpdump抓取的数据。...

继续阅读

Mac下部署Android开发环境附加NDK 作为开发者,我们深有体会,不管是进行什么开发,为了部署开发环境,我们往往需要折腾很长时间、查阅很多资料才能完成,而且这次折腾完了,下次到了另一台新电脑上又得重新来过,整个部署过程记得还好,要是不记得又得重新开始,而且遇到Android这种GFW阻隔了开发资源下载链接的环境部署,又尤其浪费时间。所以这也是我写下这篇教程的初衷跟动力源泉,希望大家参考了这篇教程以后可以轻轻松松在Mac系统下将Android环境部署好。...

继续阅读

稍顯嚴肅的台中 坦白說,留在腦海中的台中影像並不多,來台灣之前在Booking上只訂到了台中的一家青旅,第一次住青旅有些不習慣,幹什麼都放不開。 同屋的一個男生是台灣人,不過一年中四分之三的時間在上海跟北京,這麼說來跟我還是比較有共同話題的。得之我準備花15天的時間環島,覺得太倉促了,他們大學時期花一個半月的時間也不見得能將台灣島給逛完。我只能無奈地表示,兩岸允許的簽證時間有限,自己的空閒時間更有限,只能用打卡式的旅行了,我深知正真地旅行應該慢下來,融入當地的環境,感受他們的風土人情,但第一次只能這樣作罷,以後換成民進黨上台,形勢會變成怎樣還不得而知,能否再過來還是個未知數。而我一向信奉的人生格言是秉燭夜遊,活在當下,所以,理解自己吧。...

继续阅读

為之留戀的新竹 來新竹之前本沒有對她有過高的期待,慢慢對她加分要從桃園火車站出發前往新竹開始。 在桃園火車站的候車月台上,有醒目的旅遊資料發放處,這上面的擺放的全是新竹的旅遊宣傳資料,關鍵的是資料做得非常簡潔易懂,而接下來一天的新竹之行就全部是依據這份寶典的指引來完成的。...

继续阅读

從桃園開始台灣之行 初到台灣恰逢華夏銀行系統升級,特意準備的華夏銀聯卡在桃園機場沒能派上用場,只好用建行在機場5000塊,算下來是很不划算的,但是沒辦法,誰叫我出機場就得花錢呢。 從機場打車到桃園的酒店,花了將近六百塊新台幣,到酒店時五點多,天已經漸亮了,洗漱完等到七點吃過早餐就開始補覺囉,一覺醒來已是中午,帶著換下來的衣服外出找自助洗衣店,順便覓食。...

继续阅读

  • Prev
  • Next

网络异常检查

2

文章分类 : C语言, Linux, Windows, 应用与编程, 网络

一、本文目的

在涉及网络编程的实际项目应用中,由于网络不可能一直处于理想状态,TCP长连接也可能随时正常或异常地断开,如果不予处理,那么就可能因此而给程序带来很多潜在的问题。 编写该文档的目的就在于针对网络程序中可能遇到的各种问题,拿出来与大家探讨一下具体问题的解决方案,同时本人将前期调研的一些解决方案列出来,抛砖引玉,希望可以集思广益,寻求到更加合理的解决方案。    

二、网络断开时机

1、正常网络断开

(1) CS 一方调用 Close

(2) CS 一方程序正常退出,如Ctrl + C 事件可以被系统检测到,对应的套接字也将被系统标记为已断开。

2、异常网络断开

(1) CS 一方网线被拨出

(2) CS 之间路由故障,物理连接断开

(3) CS 一方断电或当机

(4) CS 一方无线信号不佳或无线接口被关闭

(5) CS 一方更改 IP 事件无法被系统检测到,这个时候读数据不会出错,只会一直阻塞着;写数据在缓冲区未满之前也不会返回错误。若无法及时检测到断开事件,对某些应用场景而言可能存在致命的错误。如服务端维护的客户端在线信息错误等。

三、网络断开常用检测方法

1、处理正常网络断开

(1) select 捕捉可读事件,read返回0

(2) epoll 捕捉可读事件,read返回0

(3) 主动 read 返回错误

(4) 主动 write 返回错误

2、处理异常网络断开

(1) 应用层KeepAlive检测

在应用层协议加入心跳握手机制,维护服务端跟客户端之间的连通状态,是最普遍最保险的办法。 客户端定时向服务端发送探测包,若服务端回应则说明服务端在线,否则作离线处理;服务端也可对长期未发送探测包的客户端作离线处理。 该方案所有系统都支持,跨平台性好;对端跟自身出现网络故障都能检测到。不足之处在于它需要应用层协议支持,程序内部需要长期维护心跳握手包,相对比较繁琐。

(2) 传输层KeepAlive检测

除了应用层 KeepAlive 检测机制外,TCP 内部也集成了 KeepAlive 机制,默认关闭,开启它很方便。对端跟自身出现网络故障都能检测到。但不是所有的系统都支持,而且有些系统虽然支持但会影响到所有套接字,消耗额外的宽带和流量,不建议使用。

//启用心跳机制,如果您想关闭,将keepAlive置零即可
setsockopt(fd,SOL_SOCKET,SO_KEEPALIVE,(void*)&keepAlive,sizeof(keepAlive));
//启用心跳机制开始到首次心跳侦测包发送之间的空闲时间
setsockopt(fd,SOL_TCP,TCP_KEEPIDLE,(void *)&start,sizeof(start));
//两次心跳侦测包之间的间隔时间
setsockopt(fd,SOL_TCP,TCP_KEEPINTVL,(void *)&interval,sizeof(interval));
//探测次数,即将几次探测失败判定为TCP断开
setsockopt(fd,SOL_TCP,TCP_KEEPCNT,(void *)&count,sizeof(count));

(3) 网络层KeepAlive检测

Ping 命令几乎是所有平台的网络连通性检测命令,走网络层 ICMP 协议,这里考虑使用 popen 函数调用系统自带的 Ping 命令来封装网络连通性检测函数。它实际上也是一种网络层的 KeepAlive 机制。

int checkConnect(char *dst, int cnt)
{
    FILE *stream;
    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;
}

dst 指定要检测的目的地址,cnt 指定 Ping 尝试的次数,-i 参数指定 Ping 尝试的超时时间。

(4) 应用层监控内核消息机制

Netlink 是一种特殊的套接字,为2.6.14及更高版本的Linux所特有,通过它,应用层程序可以方便地向内核订制指定消息,如网卡上下线。也可以设置或查询配置,如IP、路由、网络流量信息等。

a、创建一个 netlink 套接字:

fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);

b、绑定路由多播组,监控网卡信息:

addr.nl_family = AF_NETLINK;
addr.nl_groups = RTNLGRP_LINK; //指定接收路由多播组消息
bind(fd, (struct sockaddr*)&addr, sizeof(addr));

c、监听套接字,一旦可读,解析其内容,实时监控网卡上下线事件。

优点:实时性高,使用方便。

缺点:跨平台性不佳,只能检测自身网络故障。

(5) 应用层网卡信息轮询机制

网卡信息轮询机制就是定期调用 ioctl 函数执行如下操作:

struct ifconf ifc;
struct ifreq ifrcopy;
//获取网卡信息列表
ioctl(fd, SIOCGIFCONF, (char *)&ifc);
//获取网卡上下线状态
ioctl(fd, SIOCGIFFLAGS, &ifrcopy);
//获取 MAC 地址
ioctl(fd, SIOCGIFHWADDR, (char *)(&ifrcopy);
//获取 IP 地址
ioctl(fd, SIOCGIFADDR, (char *)&ifrcopy);
//获取广播地址
ioctl(fd, SIOCGIFBRDADDR, &ifrcopy));

缺点:

a、跨平台性不佳。

可以成功移植到 Linux、Android、Windows平台,但由于 iPhone 平台上获取MAC跟IP的参数不同,需特殊处理。

b、实时性跟灵活性不高。

c、耗费资源,影响性能。

d、只能检测自身网络故障。

除非注明,文章均为CppLive 编程在线原创,转载请注明出处,谢谢。

本文地址:https://www.cpplive.com/html/1670.html

评论 (2)

这里因为你的留言而存在!!!

You must be logged in to post a comment.