Tcp之心跳包

心跳包

跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着。

事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很小的包,或者只包含包头的一个空包。
在TCP的机制里面,本身是存在有心跳包的机制的,也就是TCP的选项:SO_KEEPALIVE。系统默认是设置的2小时的心跳频率。但是它检查不到机器断电、网线拔出、防火墙这些断线。而且逻辑层处理断线可能也不是那么好处理。一般,如果只是用于保活还是可以的。
心跳包一般来说都是在逻辑层发送空的echo包来实现的。下一个定时器,在一定时间间隔下发送一个空包给客户端,然后客户端反馈一个同样的空包回来,服务器如果在一定时间内收不到客户端发送过来的反馈包,那就只有认定说掉线了。
其实,要判定掉线,只需要send或者recv一下,如果结果为零,则为掉线。但是,在长连接下,有可能很长一段时间都没有数据往来。理论上说,这个连接是一直保持连接的,但是实际情况中,如果中间节点出现什么故障是难以知道的。更要命的是,有的节点(防火墙)会自动把一定时间之内没有数据交互的连接给断掉。在这个时候,就需要我们的心跳包了,用于维持长连接,保活。
在获知了断线之后,服务器逻辑可能需要做一些事情,比如断线后的数据清理呀,重新连接呀……当然,这个自然是要由逻辑层根据需求去做了。
 总的来说,心跳包主要也就是用于长连接的保活和断线处理。一般的应用下,判定时间在30-40秒比较不错。如果实在要求高,那就在6-9秒。

为什么需要心跳包?

TCP的KeepAlive保活机制

因为要考虑到一个服务器通常会连接多个客户端,因此由用户在应用层自己实现心跳包,代码较多 且稍显复杂,而利用TCP/IP协议层为内置的KeepAlive功能来实现心跳功能则简单得多。 不论是服务端还是客户端,一方开启KeepAlive功能后,就会自动在规定时间内向对方发送心跳包, 而另一方在收到心跳包后就会自动回复,以告诉对方我仍然在线。 因为开启KeepAlive功能需要消耗额外的宽带和流量,所以TCP协议层默认并不开启KeepAlive功 能,尽管这微不足道,但在按流量计费的环境下增加了费用,另一方面,KeepAlive设置不合理时可能会 因为短暂的网络波动而断开健康的TCP连接。并且,默认的KeepAlive超时需要7,200,000 MilliSeconds, 即2小时,探测次数为5次。对于很多服务端应用程序来说,2小时的空闲时间太长。因此,我们需要手工开启KeepAlive功能并设置合理的KeepAlive参数。

如何开启KeepAlive?

KeepAlive并不是默认开启的,在Linux系统上没有一个全局的选项去开启TCP的KeepAlive。需要开启KeepAlive的应用必须在TCP的socket中单独开启。Linux Kernel有三个选项影响到KeepAlive的行为:

1.net.ipv4.tcpkeepaliveintvl = 75
2.net.ipv4.tcpkeepaliveprobes = 9
3.net.ipv4.tcpkeepalivetime = 7200

tcpkeepalivetime的单位是秒,表示TCP链接在多少秒之后没有数据报文传输启动探测报文; tcpkeepaliveintvl单位是也秒,表示前一个探测报文和后一个探测报文之间的时间间隔,tcpkeepaliveprobes表示探测的次数。

TCP socket也有三个选项和内核对应,通过setsockopt系统调用针对单独的socket进行设置:

TCPKEEPCNT: 覆盖 tcpkeepaliveprobes
TCPKEEPIDLE: 覆盖 tcpkeepalivetime
TCPKEEPINTVL: 覆盖 tcpkeepalive_intvl

举个例子,以我的系统默认设置为例,kernel默认设置的tcpkeepalivetime是7200s, 如果我在应用程序中针对socket开启了KeepAlive,然后设置的TCP_KEEPIDLE为60,那么TCP协议栈在发现TCP链接空闲了60s没有数据传输的时候就会发送第一个探测报文。

心跳包实现为什么要在服务端?

心跳包所以实现在服务器侧,是因为与客户端相比,服务器侧的寿命更长,因为服务器侧需要不间断地提供服务,而客户端可能由于用户下班而合上电脑(TCP没有来得及发送FIN关闭连接),这样的话,服务器侧就会有很多不可用的TCP连接(established),这样的连接依然会占用服务器内存资源,于是就设计这个keepalive 来检测客户端是否可用,如果几次重传keepalive ,客户端没有相应,删除连接,释放资源。需要指出的是,超时时间是指TCP连接没有任何数据、控制字传输的时间,如果有任何数据传输,会刷新定时器,重新走表。

为什么需要实现应用层心跳包?

KeepAlive是实现在TCP协议栈(四层),我们需要自己实现的应用层心跳在第七层,本质没有任何区别。

心跳除了说明应用程序还活着,进程还在,网络通畅,更重要的是表明应用程序还能正常工作,而TCP keepalive由操作系统负责探测,即便进程死锁或者阻塞,操作系统也会如常收发TCP keepalive消息,对方无法得知这一异常。

它检查不到机器断电、网线拔出、防火墙这些断线。而且逻辑层处理断线可能也不是那么好处理。一般,如果只是用于保活还是可以的。

应用层需要独立实现自己的心跳,是因为超时时间较长,无法给应用层提供快速的反馈,不能满足人们的实时性的要求。另外应用层需要自己来定义心跳包格式。

心跳包的实现

心跳协议的基本形式:如果进程C依赖S,那么S应该按固定周期向C发送心跳,而C按固定周期来检测心跳。换言之,通常是服务端向客户端发送心跳。

心跳包的检测步骤:

1服务端每隔一个时间间隔发生一个探测包给客户端
2服务端发包时启动一个超时定时器
3客户端端接收到检测包,应该回应一个包
4如果服务端收到客户端的应答包,则说明客户端正常,删除超时定时器
5如果服务端端的超时定时器超时,依然没有收到应答包,则说明客户端挂了

TCP心跳包的实现可以参考一下这篇博文:https://www.cnblogs.com/scy251147/p/3333957.html

Tcp之心跳包的更多相关文章

  1. TCP socket心跳包示例程序

    在做游戏开发时,经常需要在应用层实现自己的心跳机制,即定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性. 在TCP socket心跳机制中,心跳包可以由服务器发送给客户端 ...

  2. TCP之心跳包实现思路

    说起网络应用编程,想到最多的就是聊天类的软件.当然,在这类软件中,一般都会有一个用户掉线检测功能.今天我们就通过使用自定义的HeartBeat方式来检测用户的掉线情况. 心跳包实现思路 我们采用的思路 ...

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

    很多应用层协议都有HeartBeat机制,通常是客户端每隔一小段时间向服务器发送一个数据包,通知服务器自己仍然在线,并传输一些可能必要的数据.使用心跳包的典型协议是IM,比如QQ/MSN/飞信等协议. ...

  4. TCP连接探测中的Keepalive和心跳包

    TCP连接探测中的Keepalive和心跳包 tcp keepalive 心跳 保活 Linuxtcp心跳keepalive保活1. TCP保活的必要性 1) 很多防火墙等对于空闲socket自动关闭 ...

  5. TCP连接探测中的Keepalive 和心跳包

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

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

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

  7. tcp/心跳包

    1,http://blog.csdn.net/yuzhiyuxia/article/details/7857508 心跳包就是在客户端和服务器间定时通知对方自己状态的一个自己定义的命令字,按照一定的时 ...

  8. TCP/UDP区别&&心跳包机制【转】

    转自:https://www.jianshu.com/p/6d93a3c21c34 UDP:用户数据报协议:主要用在实时性要求比较高的以及对质量相对较弱的地方.但是面对现在高质量的线路不会容易丢包,除 ...

  9. *关于TCP长连接,NAT超时,心跳包

    参考: http://www.jianshu.com/p/584707554ed7 1.TCP长连接 TCP连接建立后只要不明确关闭,逻辑上连接一直存在. TCP是有保活定时器的,可以打开保活定时器来 ...

随机推荐

  1. Coding Rules

    c语言按行读取的时候,注意用fgets可以读一行,但默认会把换行符也读进去,使用scanf("%s")却不会.

  2. LC 954. Array of Doubled Pairs

    Given an array of integers A with even length, return true if and only if it is possible to reorder ...

  3. Hibernate HelloWorld案例

    搭建一个Hibernate环境,开发步骤: 1. 下载源码 版本:hibernate-distribution-3.6.0.Final 2. 引入jar文件          hibernate3.j ...

  4. notepad++ 插件说明(一)

    notepad++插件说明(一) 1.xml插件安装 下载地址:https://sourceforge.net/projects/npp-plugins/files/XML%20Tools/Xml%2 ...

  5. Sqlserver实现故障转移 — sqlserver镜像备份实现故障转移(3)

    目的:在已经加域的计算机上安装sqlserver2012,并配置数据库镜像实时同步,并实现故障转移. 在数据库层面实现故障自动转移后,应用程序里改怎么写数据库连接呢?其实使用ADO.NET或者SQL ...

  6. XCTF (app1)

    打开app.一个文本框,随便输入提示如下图. 打开JEB反编译. v2调用getPackageInfo获取版本信息.一般 Android 通过 PackageInfo 这个类来获取应用安装包信息,比如 ...

  7. <转>常规测试方法

    功能测试 1. 安装测试: 安装过程中对于缺省安装目录及任意指定的安装目录,是否都能正确安装: 若是选择安装,查看能否实现其相应的功能: 在所有能中途退出安装的位置退出安装程序后,验证此程序并未安装成 ...

  8. C#编程 线程,任务和同步(2) 开启线程

    创建线程的几种方法: 1 异步委托 创建线程的一种简单方式是定义一个委托,并异步调用它. 委托是方法的类型安全的引用.Delegate类 还支持异步地调用方法.在后台,Delegate类会创建一个执行 ...

  9. python selenium 实战涉及很多知识点

    1.iframe的切入和切出 #切入 driver.switch_to.frame(driver.find_element_by_id('iFrame_1')) # 切换出来 driver.switc ...

  10. 2019牛客暑期多校训练营(第一场)-E(DP)

    题目链接:https://ac.nowcoder.com/acm/contest/881/E 题意:求可分解成n个AB和m个BA的字符串的个数. 思路: 首先根据贪心思想,前n个A可作为AB的A,后m ...