1. TCP保活的必要性

1) 很多防火墙等对于空闲socket自动关闭

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

2. 导致TCP断连的因素

如果网络正常, socket也通过close操作来进行优雅的关闭, 那么一切完美. 可是有很多情况, 比如网线故障, 客户端一侧突然断电或者崩溃等等, 这些情况server并不能正常检测到连接的断开.

3. 保活的两种方式:

1) 应用层面的心跳机制

自定义心跳消息头. 一般客户端主动发送, 服务器接收后进行回应(也可以不回应). 这里不进行详述.

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

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

打开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 plain copy
  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_TCP和TCP_KEEPIDLE等3个宏找不到.

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

链接推荐:

闲说HeartBeat心跳包和TCP协议的KeepAlive机制

TCP Keepalive HOWTO

TCP连接探测中的Keepalive和心跳包相关推荐

  1. linux内核协议栈 TCP连接探测中的Keepalive和心跳包使用

    目录 1 TCP保活的必要性 2 导致TCP断连的因素 3 保活的两种方式 3.1 应用层面的心跳机制 3.2 TCP协议自带的保活功能 4 两种方式的优劣性 5 到底选用那种心跳方式? 6 配置 K ...

  2. TCP连接探测中的Keepalive和心跳包. 关键字: tcp keepalive, 心跳, 保活

    1. TCP保活的必要性 1) 很多防火墙等对于空闲socket自动关闭 2) 对于非正常断开, 服务器并不能检测到. 为了回收资源, 必须提供一种检测机制. 2. 导致TCP断连的因素 如果网络正常 ...

  3. tcp连接探测Keepalive和心跳包

    采用TCP连接的C/S模式软件,连接的双方在连接空闲状态时,如果任意一方意外崩溃.当机.网线断开或路由器故障,另一方无法得知TCP连接已经失效,除非继续在此连接上发送数据导致错误返回.很多时候,这不是 ...

  4. go tcp连接_TCP漫谈之keepalive和time_wait

    TCP是一个有状态通讯协议,所谓的有状态是指通信过程中通信的双方各自维护连接的状态. 一.TCP keepalive 先简单回顾一下TCP连接建立和断开的整个过程.(这里主要考虑主流程,关于丢包.拥塞 ...

  5. TCP连接的心跳包机制

    文章目录 什么是心跳机制 为什么需要心跳机制? 如何及时有效地检测到另一方的非正常断开 TCP的keeplive保活机制 什么是心跳机制 所谓的心跳包就是(探测性的)数据包,之所以叫心跳包是因为:它像 ...

  6. Socket连接心跳包的机制总结

    文章目录 Socket连接心跳包的机制总结 心跳包的由来 心跳包的作用 心跳包由服务端还是客户端发送? Socket连接心跳包的机制总结 心跳包的由来 心跳包之所以叫心跳包是因为:它像心跳一样每隔固定 ...

  7. muduo网络库学习(五)服务器监听类Acceptor及Tcp连接TcpConnection的建立与关闭

    通常服务器在处理客户端连接请求时,为了不阻塞在accept函数上,会将监听套接字注册到io复用函数中,当客户端请求连接时,监听套接字变为可读,随后在回调函数调用accept接收客户端连接.muduo将 ...

  8. 【Socket】关于socket长连接的心跳包

    TCP的socket本身就是长连接的,那么为什么还要心跳包呢? 在smack里有个30s发送一个空消息的线程,同样关于心跳包(keepalive) 据网络搜索到的资料解释如下 内网机器如果不主动向外发 ...

  9. 关于socket长连接的心跳包

    出于最近对im研究的兴趣,看到smack里有个30s发送一个空消息的线程,了解了下关于心跳包,keepalive的知识. TCP的socket本身就是长连接的,那么为什么还要心跳包呢? 搜索到的资料解 ...

最新文章

  1. 综述 | 语言分析技术在社会计算中的应用
  2. 今年双11,200所大学快递无人送
  3. 5.4 SVM的使用建议-机器学习笔记-斯坦福吴恩达教授
  4. idea社区版和企业版区别_IntelliJ IDEA 旗舰版与社区版有什么不同
  5. idea中自动deployment的步骤
  6. 从SQL Server到多数据库,微软数据库迁移全攻略
  7. ReactRouter的实现
  8. 安卓学习笔记09:常用布局 - 帧式布局
  9. 中常用的函数_ST语言编程中常用的函数/功能块
  10. 重拾阅读--朝花夕拾啊
  11. Java 动态代理机制详解
  12. 音视频之hls rtmp rtsp 视频流测试地址
  13. 芯片破壁者(十五):仙童半导体和“八叛逆”所缔造的“硅谷模式”
  14. oracle 常用统计函数,Oracle常用的统计函数
  15. 跟着杨中科学习asp.net之javascript
  16. python爬取谷歌图片_Python 爬取谷歌街景图片
  17. 自动将视频文件生成字幕的软件autosub安装及使用(支持英文、日语和法语)
  18. 常见条形码的用法和格式
  19. XP系统清理优化工具箱
  20. 华为od机考真题-统计射击比赛成绩

热门文章

  1. 预处理指令if、ifdef、ifndef
  2. VR全景图之处理美化RAW图片既拍摄出来的照片
  3. 修改微信小程序默认返回键,使用onUnload
  4. mysql的实训报告论文_数据库实验报告范文
  5. 神经网络的万能逼近定理
  6. mysql数据库 purge_MySQL数据库之Purge死锁问题解析
  7. 设计模式 行为型模式 实例 -- 备忘录模式实例:游戏备忘录
  8. TCL联袂爱奇艺,能碰出什么不一样的火花?
  9. MSM8909读PMIC芯片寄存器
  10. fcitx 搜狗输入法100%CPU占用解决方法