Linux 网络编程中之心跳机制应用
来源:互联网 发布:淘宝修改为没有发货 编辑:程序博客网 时间:2024/04/28 07:17
Linux 网络编程中之心跳机制应用
一、问题:Linux TCP 中如何判断非正常连接的断开
二、方法分析:
面向连接的TCP连接,在实际的应用中经常需要检测连接是否断开。而在实际的连接过程中,连接断开分为两种情况:
1、客户端正常关闭。即客户端通过调用close,shutdown来正常关闭socket。此时服务端通过read和write的返回值来判断客户端是否正常
关闭0表示,-1表示读写错误。均可以表示连接正常断开。
2、客户端非正常关闭。比如说网络断开,wifi连接失效断开等的非正常断开。此时,不能通过read和write判断,这两个函数将不能判断
socket已经失效。需要通过其他方式来判断连接是否断开。判断方式有以下两种:
1、TCP通信的双方定时发送数据包,通过判断是否收到对方的数据包以检测对方是否在线。
2、利用Socket的KEEP_ALIVE 机制,来定时给对方发送一个"探测存活数据包",当超过一定时间对方没有回复ACK,则视为连接断开,此时
调用read或者write时,将返回错误信息。我们可以通过判断错误信息来检测链接已经断开。
两者的优劣:
方法一:需要客户端与服务端协商好双方的通信协议,需要双方的应用层程序通信作出修改,比较不灵活。
方法二:默认状态下,KEEP_ALIVE 机制判断tcp链接是否断开需要发送心跳包来检测,由于发送心跳包的工作由tcp得协议栈来做,应用层只需要
对链接两端的TCP socket 设置keep alive 机制,进行监听即可。这种方法实现较为方便。
三、注意事项:
KEEP_ALIVE 机制默认发送心跳包的首次空闲时间为:2小时(7200s),但在实际应用中,我们需要实时监听对方是否在线,因此需要对KEEP_ALIVE 相关参数做出调整。并且当检测到链接断开时,keep_alive 不会自动通知上层,需要应用层通过read 和 write 的返回值确定。0
或-1均表示,链接已断开。
四、相关参数设置:
Linux内核包含对keepalive的支持。其中使用了三个参数:
tcp_keepalive_time(开启keepalive的闲置时长/首次探测空闲时间),表示tcp连接双方没有数据交换的空闲时间。
tcp_keepalive_intvl(keepalive探测包的发送间隔)tcp_keepalive_probes (如果对方不予应答,探测包的发送次数);对于异常关闭如网络崩溃、主机宕机等,可通过设置SO_KEEPALIVE设置保活,协议会按照设定间隔自动发送探测分节。该选项分为设置无数据首次探测时间、探测间隔、探测次数控制TCP是否出错。如果你设置首次探测在10秒之后、探测间隔3s,探测次数3次,则最多在10+3*3=19秒之后(最少在3*3=9秒),将给应用层返回一个对方非正常关闭的异常,此时可通过获得errno得到对应错误,read/recv返回为-1。
修改方法有以下两种:
1、系统配置:分别修改以下三个参数
# cat /proc/sys/net/ipv4/tcp_keepalive_time7200# cat /proc/sys/net/ipv4/tcp_keepalive_intvl75# cat /proc/sys/net/ipv4/tcp_keepalive_probes9
2、应用编程:见下方例子(仅列出主要头文件)
/* 仅列出主要头文件 */#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <unistd.h>/* 调用方法 * sg_socketfd 为服务端的监听socket */anetKeepAlive(NULL, sg_socketfd, 6);/* TCP 心跳包检测 *//* Set TCP keep alive option to detect dead peers. The interval option * is only used for Linux as we are using Linux-specific APIs to set * the probe send time, interval, and count. */int ANET_ERR = -1;int anetKeepAlive(char *err, int fd, int interval){ int val = 1; /* 开启keepalive机制 */ if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1) { perror("setsockopt SO_KEEPALIVE:"); return ANET_ERR; } /* Default settings are more or less garbage, with the keepalive time * set to 7200 by default on Linux. Modify settings to make the feature * actually useful. */ /* 开始首次KeepAlive探测前的TCP空闲时间 * Send first probe after interval. */ val = interval; if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) { perror("setsockopt TCP_KEEPIDLE: \n"); return ANET_ERR; } /* 两次KeepAlive探测间的时间间隔 * Send next probes after the specified interval. Note that we set the * delay as interval / 3, as we send three probes before detecting * an error (see the next setsockopt call). */ val = interval/3; if (val == 0) val = 1; if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) { perror("setsockopt TCP_KEEPINTVL: \n"); return ANET_ERR; } /* 判定断开前的KeepAlive探测次数 * Consider the socket in error state after three we send three ACK * probes without getting a reply. */ val = 3; if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) { perror("setsockopt TCP_KEEPCNT: \n"); return ANET_ERR; } return 0;}
0 0
- Linux 网络编程中之心跳机制应用
- LINUX C网络编程中的心跳机制
- LINUX C网络编程中的心跳机制
- LINUX C网络编程中的心跳机制
- 网络之心跳机制
- linux网络编程---心跳检测
- Python网络编程:实现心跳机制
- Linux Socket编程中的心跳机制
- Linux socket编程的心跳机制总结
- Linux Socket编程中的心跳机制
- Linux Socket编程中的心跳机制
- linux应用之--网络编程
- Java之心跳机制
- Linux网络应用编程之交换机概述
- Linux应用程序设计之网络基础编程
- 【项目】基于TCP/IP的socket编程之心跳机制
- java网络编程之Netty实战心跳检测(八)
- 网络编程之应用
- poj2282(组合数学,数位上的dp)
- 全局描述符表
- 什么是线程?线程相关的概念?
- AJAX编写格式
- C语言题集-综合提高(题目)
- Linux 网络编程中之心跳机制应用
- [HDOJ]2016
- 分布式服务框架 Zookeeper -- 管理分布式环境中的数据
- javascript 浏览器版本检测
- DisplayMetrics用法
- c语言题集-综合提高(部分答案)
- NYOJ 659 判断三角形【简单题】
- 第十六周 项目三:用函数指针调用函数
- 第十六周项目1