Tcp之心跳包
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之心跳包的更多相关文章
- TCP socket心跳包示例程序
在做游戏开发时,经常需要在应用层实现自己的心跳机制,即定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性. 在TCP socket心跳机制中,心跳包可以由服务器发送给客户端 ...
- TCP之心跳包实现思路
说起网络应用编程,想到最多的就是聊天类的软件.当然,在这类软件中,一般都会有一个用户掉线检测功能.今天我们就通过使用自定义的HeartBeat方式来检测用户的掉线情况. 心跳包实现思路 我们采用的思路 ...
- 闲说HeartBeat心跳包和TCP协议的KeepAlive机制
很多应用层协议都有HeartBeat机制,通常是客户端每隔一小段时间向服务器发送一个数据包,通知服务器自己仍然在线,并传输一些可能必要的数据.使用心跳包的典型协议是IM,比如QQ/MSN/飞信等协议. ...
- TCP连接探测中的Keepalive和心跳包
TCP连接探测中的Keepalive和心跳包 tcp keepalive 心跳 保活 Linuxtcp心跳keepalive保活1. TCP保活的必要性 1) 很多防火墙等对于空闲socket自动关闭 ...
- TCP连接探测中的Keepalive 和心跳包
采用TCP连接的C/S模式软件,连接的双方在连接空闲状态时,如果任意一方意外崩溃.当机.网线断开或路由器故障,另一方无法得知TCP连接已经失效,除非继续在此连接上发送数据导致错误返回.很多时候,这不是 ...
- TCP连接探测中的Keepalive和心跳包. 关键字: tcp keepalive, 心跳, 保活
1. TCP保活的必要性 1) 很多防火墙等对于空闲socket自动关闭 2) 对于非正常断开, 服务器并不能检测到. 为了回收资源, 必须提供一种检测机制. 2. 导致TCP断连的因素 如果网络正常 ...
- tcp/心跳包
1,http://blog.csdn.net/yuzhiyuxia/article/details/7857508 心跳包就是在客户端和服务器间定时通知对方自己状态的一个自己定义的命令字,按照一定的时 ...
- TCP/UDP区别&&心跳包机制【转】
转自:https://www.jianshu.com/p/6d93a3c21c34 UDP:用户数据报协议:主要用在实时性要求比较高的以及对质量相对较弱的地方.但是面对现在高质量的线路不会容易丢包,除 ...
- *关于TCP长连接,NAT超时,心跳包
参考: http://www.jianshu.com/p/584707554ed7 1.TCP长连接 TCP连接建立后只要不明确关闭,逻辑上连接一直存在. TCP是有保活定时器的,可以打开保活定时器来 ...
随机推荐
- 评CSDN上一篇讲述数据迁移的文章“程序员 12 小时惊魂记:凌晨迁移数据出大事故!”
原文地址:https://blog.csdn.net/csdnnews/article/details/98476886 我的评论:热数据迁移,本不该搞突击,这样一旦出现问题后果不堪设想,多少DBA和 ...
- C# 防火墙操作之开启与关闭
通过代码操作防火墙的方式有两种:一是代码操作修改注册表启用或关闭防火墙:二是直接操作防火墙对象来启用或关闭防火墙.不论哪一种方式,都需要使用管理员权限,所以操作前需要判断程序是否具有管理员权限. 1. ...
- 求平面上N点最远两点和最近两点距离
最近两点,二分法 最远两点,凸包+找对踵点
- C++ 学习安排
第一阶段主要是理解概念及最基本的定义和声明包含以下内容:1. 头文件2. 命名空间3. 变量和基本类型4. 函数5. 类6. 标准库类型第二部分进阶入门,主要学习C++中的某些内容的特殊性及逻辑编写1 ...
- sql中对查询出的某个字段转换查询
<select id="queryCmonByLanId" parameterType="java.util.Map" resultType=" ...
- 阶段3 3.SpringMVC·_06.异常处理及拦截器_7 SpringMVC拦截器之拦截器接口方法演示
返回值改成false 就是不放行 没有方形,控制台只有一个输出 转发到error页面 新建error.jsp页面 控制台只有拦截器的输出.controller根本就没有执行 把代码改回来 重写第二个方 ...
- 国内npm源
永久使用lnpm config set registry https://registry.npm.taobao.org // 配置后可通过下面方式来验证是否成功 npm config get reg ...
- Linux 查找特定程序 whereis
Linux 查找特定程序 whereis whereis 命令主要用于查找程序文件,并提供这个文件的二进制可执行文件.源代码文件和使用手册存放位置. 1.查找命令程序 例如,查找 touch 命令 [ ...
- nginx创建www用户作用
linux创建www用户组和用户 wdcp中的nginx服务启动需要依赖www用户,因此若没有此用户就可能会启动失败.创建这个用户的方法: [root@bogon local]# id www [ro ...
- java:WebService
1.WebService就是应用之间的远程调用,可以跨语言调用,为甚么可以跨语言调用,是因为其实依赖与xml语言,xml语言依赖http协议,http协议底层也是socket.