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

news/2025/6/8 15:51:57

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个属性, 使用简单, 如下:

 

  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

文章来源:https://shuqi.blog.csdn.net/article/details/75127439
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:https://dhexx.cn/news/show-3765459.html

相关文章

Linux 内存 CPU查看

cat /proc/meminfo 查看RAM使用情况最简单的方法是通过/proc/meminfo。 这个动态更新的虚拟文件实际上是许多其他内存相关工具(如&#xff1a;free / ps / top)等的组合显示。 /proc/meminfo列出了所有你想了解的内存使用情况。 进程的内存使用信息也可以通过/proc/<pid…

刘谦魔术揭秘:数硬币

看完了今天晚上湖南卫视的魔术节目&#xff0c;最后刘谦做了一个数硬币的魔术&#xff0c;随意让三个人上台来在一个盘子里抓一把硬币&#xff0c;然后靠“透视”来说出每个人手中的硬币的准确数量。 话说该人两个月没出来表演新魔术&#xff0c;这一出应该很让人叫绝了&#x…

govendor使用

一&#xff0c;开发端 前提是有一个已经go get过依赖包&#xff0c;并编译成功的项目。 $ go get -u github.com/kardianos/govendor $ cd project_dir $ govendor init $ govendor add e 二、部署端 git clone 下来该项目。 $ cd project_dir $ go run main.go 即可。转载于:h…

docker-compose一键部署 Elasticsearch Logstash Kibana

文章目录 1. 需求背景 2. 部署 2.1 目录说明 2.2 配置文件 2.2.1 docker-compose.yml 2.2.2 elasticsearch.yml&#xff08;容器内 config/elasticsearch.yml&#xff09; 2.2.3 kibana.yml 2.2.4 logstash.yml &#xff08;容器内 config/logstash.yml&#xff09; 2.2.5 logs…

发一个我自己写的.net中使用的缓存封装类(算是第三版了)

发一个我自己写的.net中使用的缓存封装类&#xff08;算是第三版了&#xff09; 先上代码&#xff1a; WebCache Classusing System;using System.Data;using System.Configuration;using System.Web;using System.Collections;using System.Text;namespace Web{ /**//// &…

CIFS, NFS, iSCSI, UNC

在数据存储中&#xff0c;存储设备与服务器的连接方式通常有三种形式&#xff1a; 1、存储设备与服务器直接相连接--DAS&#xff1b; 2、存储设备直接联入现有的TCP/IP的网络中--NAS&#xff1b; 3、将各种存储设备集中起来形成一个存储网络&#xff0c;以便于数据的集中管理--…

cadivsor实现docker监控

1.cAdvisor (Container Advisor)该程序是由Google 开源的一个项目。提供了给使用容器的用户对其主机上运行容器的资源使用情况和性能的了解&#xff0c;它是一个以容器方式运行的守护进程&#xff0c;用来数据采集、汇聚、可视化和导出运行中容器的信息。具体来说&#xff0c;对…

公交见闻

小弟在武汉上班,每天都挤公交上班,没办法啊,工薪阶层的无奈.坐的多了,见得也多了.比如说今天吧,我坐的那路车每天上下班特别挤,而且起点还是火车站.挤习惯了,看见再挤的车我也无所畏惧了,直接上.可怜的我啊&#xff0c;脸一直贴着后门玻璃。也不知到了哪一站上来一个中年妇女,长…

ESP8266_SDK基础(4)WiFi快连smartConfig

环境及工具与第一章相同&#xff0c;这里就不在重复&#xff01; 本章通过代码示例&#xff0c;来实现wifi模块连接到路由器的功能&#xff0c;模块开机上电是自动进入快连模式&#xff0c;待30秒后退出快连模式&#xff0c;若连接成功则运行正常程序&#xff0c;若未连接成功&…

MongoDB基本管理命令 .

http://blog.csdn.net/shirdrn/article/details/7105539