TCP链接探测中的Keepalive和心跳包

1. TCP保活的必要性服务器

1) 不少防火墙等对于空闲socket自动关闭网络

2) 对于非正常断开服务器并不能检测到为了回收资源必须提供一种检测机制.框架


2. 致使TCP断连的因素socket

若是网络正常, socket也经过close操做来进行优雅的关闭那么一切完美但是有不少状况好比网线故障客户端一侧忽然断电或者崩溃等等这些状况server并不能正常检测到链接的断开tcp


3. 保活的两种方式:ide

1) 应用层面的心跳机制spa

自定义心跳消息头通常客户端主动发送服务器接收后进行回应(也能够不回应). 这里不进行详述..net

PS: 有人从软件的功能角度列出第三种方式就是经过第三方软件来进行探测肯定链接的有效性这种方式局限性很大并且不属于软件内部的功能实现不进行讨论.code

2) TCP协议自带的保活功能server

打开keep-alive功能便可具体属性也能够经过API设定.


4. 两种方式的优劣性

TCP协议自带的保活功能使用起来简单减小了应用层代码的复杂度推测也会更节省流量由于通常来讲应用层的数据传输到协议层时都会被加上额外的包头包尾TCP协议提供的检活其发的探测包理论上实现的会更精妙(用更少的字节完成更多的目标), 耗费更少的流量.

由应用本身实现的应用层的心跳为心跳消息额外定义一个消息类型就能够了就是应用正常的消息包只是这个包特殊点专门用来检活而已一般比较小可能只有消息头就能够了除非须要额外的信息

应用层心跳的好处我我的的理解有两点

一是比较灵活由于协议层的心跳只能提供最纯粹的检活功能可是应用层本身能够随意控制包括协议可能提供的是秒级的可是你想作成毫秒级的都任意(虽然实际几乎不会有这种时间级别的心跳), 包里还甚至能够携带额外的信息这些都是灵活之处.

二是通用应用层的心跳不依赖协议若是有一天不用TCP要改成UDP协议层不提供心跳机制了可是你应用层的心跳依旧是通用的可能只须要作少量改动就能够继续使用.

应用层心跳的很差的地方也很显而易见增长开发工做量因为应用特定的网络框架还可能很增长代码结构的复杂度再就是根据上面的推测应用层心跳的流量消耗仍是更大的毕竟这本质上仍是个普通的数据包.


5. 到底选用那种心跳方式?

优劣点第4节已经进行了阐述所以若是能肯定大家更换协议的可能性很是小同时只是须要检活的功能那么用协议自带的就绝对OK使用简单并且高效有些自负的人总喜欢用本身搞的来代替成熟协议自带的东西代替系统内核提供的东西其实每每你应用层实现的东西都是更拙劣的网上看了一些关于协议的Keep-alive不靠谱的说法也都比较空想和想固然都没有拿出任何事实论据或实验数据这点你们有看法欢迎交流哈~


6. 类Unix平台如何使用Keep-alive

keepalive默认是关闭的由于虽然流量极小毕竟是开销所以须要用户手动开启有两种方式开启.

1) 在代码里针对每一个socket进行单独设定使用起来灵活.

除了keepAlive 开关还有keepIdle, keepInterval, keepCount 3个属性使用简单以下:

[cpp] view plaincopy在CODE上查看代码片派生到个人代码片

  1. int keepAlive = 1;   // 开启keepalive属性. 缺省值: 0(关闭)  

  2. int keepIdle = 60;   // 若是在60秒内没有任何数据交互,则进行探测. 缺省值:7200(s)  

  3. int keepInterval = 5;   // 探测时发探测包的时间间隔为5秒. 缺省值:75(s)  

  4. int keepCount = 2;   // 探测重试的次数. 所有超时则认定链接失效..缺省值:9(次)  

  5. setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void*)&keepAlive, sizeof(keepAlive));  

  6. setsockopt(s, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));  

  7. setsockopt(s, SOL_TCP, TCP_KEEPINTVL, (void*)&keepInterval, sizeof(keepInterval));  

  8. setsockopt(s, SOL_TCP, TCP_KEEPCNT, (void*)&keepCount, sizeof(keepCount));  

使用时须要#include <netinet/tcp.h>, 不然SOL_TCPTCP_KEEPIDLE3个宏找不到.

ps: 忍不住吐槽一下, 网上大量绝不负责的转载, 千篇一概的搜索结果, 不少人根本都没进行过任何验证吧. 为了找这么个头文件都费了不小的事. 大多数帖子里的说的都是不可用的.

2) 修改配置文件对整个系统全部的socket有效.

咱们能够用cat命令查看到系统中这几个默认的值.

#cat /proc/sys/net/ipv4/tcp_keepalive_time  7200  

#cat /proc/sys/net/ipv4/tcp_keepalive_intvl  75  

#cat /proc/sys/net/ipv4/tcp_keepalive_probes  9

修改它们:

#echo 60 > /proc/sys/net/ipv4/tcp_keepalive_time  

#echo 5 > /proc/sys/net/ipv4/tcp_keepalive_intvl  

#echo 3 > /proc/sys/net/ipv4/tcp_keepalive_probes

相关文章
相关标签/搜索