A. iOS 即时通讯(二):心跳保活
很多人认为,TCP协议有KeepAlive机制,为何基于它的通讯链接仍然需要在应用层实现额外的心跳保活呢?本文将从移动端IM的角度告诉你,即使使用的是TCP协议,应用层的心跳保活仍旧必不可少。
在使用TCP长连接的IM服务设计中,往往都会涉及到心跳。心跳一般是指客户端每隔一定时间向服务端发送自定义指令,以判断双方是否存活,改喊因其按照一定间隔发送,类似于心跳,故称为心跳指令。
TCP是一个基于连接的协议,其连接状态是由一个状态机进行维护,连接完毕(三次握手)后,双方都会处于established状态,这之后的状态并不会主动进行变化。也就是说,即使上层不进行任何调用,一直使TCP连接空闲,那么它仍然是保持连接的状态。这个时候就需要一种机制来检测TCP连接的状态,KeepAlive就是背负这个使命出现的。
那么问题来了,KeepAlive是用来检测TCP连接状态的,那为什么还需要心跳呢?这里就需要考虑一种情况了,假如某台服务器因为某些原因导致负载超高,CPU100%,无法响应任何业务需求,但是使用TCP探针仍旧能够确定连接状态,这就是典型的连接活着但业务提供方已死的状态塌厅,对客户端而言,这时最好的选择就是断线后重新连接其他服务器,而不是一直认为当前服务器是可用状态,一直向当前服务器发送些必然后失败的请求。
从上面我们可以知道,KeepAlive并不适合检测双方存活的场景,这种场景还得依赖于应用层的心跳。应用层的心跳有着更大的灵活性,可以控制检测时机、间隔和处理流程,甚至可以在心跳包上附带额外信息。从这个角度而言,应用层的心跳的确是最佳实践。
TCP KeepAlive用于检测连接的死活,而心跳机制则附带一个额外团歼隐的功能:检测通讯双方的存活状态。
从上面我们可以得出结论,目前而言,应用层心跳的确是检测连接有效性,双方是否存活的最佳实践,那么剩下的问题就是怎么实现。
最简单粗暴的方法是定时心跳,如每隔30秒心跳一次,15秒内没有收到心跳包则认为当前连接已失效,断开连接并进行重连。这种做法最直接,实现也简单。唯一的问题就是耗电和耗流量。以一个协议包 5 个字节计算,一天收发 2880 个心跳包,一个月就是 5 x 2 x 2880 x 30 = 0.8 M 的流量,如果手机上多装几个 IM 软件,每个月光心跳就好几兆流量没了,更不用说频繁的心跳带来的电量损耗。
既然频繁心跳会带来耗电和耗流量的弊端,改进的方向自然就是减少心跳频率,但也不能过于影响连接检测的实时性。基于这个需求,一般可以将心跳间隔根据程序状态进行调整,当程序在后台时(这里主要指安卓),尽量拉长心跳间隔,5分钟、甚至10分钟都可以。
而当App在前台时则按照原来规则操作。连接可靠性的判断也可以放宽,避免一次心跳超时就认为连接无效的情况,使用错误积累,只在心跳超时n次后才判定当前连接不可用。
B. java程序里面心跳响应是什么意思
就是客户端与服务器端连接断开与否的检测,一般用于检测连接是否超时
C. 求linux c语言的心跳包程序
首先,心跳包一般是纯稿胡30秒或者1分钟一次才正常,3秒一次太频繁,耗损资源,降低效率,心跳包其实就是你自己定义敬世一条数据send给服务器,服务器recv到这条数据做下判断就行了,如果1分钟没做拦收到这条数据,就断开此客户端的socket连接,返回socket值,根据返回的值确定此客户端掉线了.
D. 为什么基于TCP的应用需要心跳包
由于连接丢失时,TCP不会立即通知应用程序。比如说,客户端程序断肆灶线了,服务端的TCP连接不会检测到断线,而是一直处于连接状芹衫态。这就带来了很大的麻烦,比如明明客户端已经断了嫌雹腔,服务端还维护着客户端的连接,照常执行着该玩家的游戏。
心跳包就是用来及时检测是否断线的一种机制,通过每间隔一定时间发送心跳数据,来检测对方是否连接。是属于应用程序协议的一部分。
E. java是否可以实现心跳的程序
java是可以实现心跳的程序的。
心跳顾名思义就是每隔一段时间执行,或者轮询查询状态,可以使用timer来实卜晌乎现,代码如下:
定时器可以实现
//1000毫秒型悉,固定时间,每隔1秒钟执行一次actionPerformed方法
javax.swing.Timerclock=newjavax.swing.Timer(1000,new谨猜ActionListener(){
publicvoidactionPerformed(ActionEvente){
//执行心跳方法
/**...*/
//调用其他方法
/**...*/
}
});
clock.start();
可以独立用个线程管理,也可以直接写在主线程中
F. 高端推荐帖:回复:PLC心跳是什么变量
PLC心跳一般是编程者编制的一个脉冲位,每间隔一段时间发一个脉冲。一般周期为1秒或者0.5秒。代表PLC正在运行。这个心并悉渣跳通常是用在两个PLC系统通讯时其中一个系统判断另外一陆腊个系统是否在正常运行绝悄。
G. 服务器怎么判断心跳包
用sendUrgentData这个来判断服务端是否异常关闭
想实现自动连接服务端,如果用
socket=锋弯newSocket("192.168.1.4",1821);
socket.connect();
只有每次启基州去new创建这个sock对象,因为只有sock对象创建好了才由输入输出流
目前的实现方式就是,
1.在原有的基础上,再开多一个线程,专门负责发送心跳,
2.先睡眠500毫秒,
3.用socket.sendUrgentData(FF),给服务端,
4.如果服务端异常关闭的话,我就捕捉这个异常。。。
5.循环
心跳的意思就是每隔一段时间,客户端给服务器发一段消息:
1、客户端:服务器,我还活着,你死了没
2、服务器:客户端,我知道你还活着这个信息,我已经记录下来了,同时告诉你我也悄蔽还活着
更多问题到问题求助专区http://bbs.hounwang.com/
H. Socket心跳包机制总结
tcp的断线检测,分为两种:
① 利用tcp自带的keep –alive机制
② 自己组建心跳包的方式向对端发送
通过Keep-alive机制对tcp的连接保持,也就渣猛腔是Tcp的心跳包,见MSDN:
If keep-alive is enabled for a TCP socket with SO_KEEPALIVE, then the default TCP settings are used for the keep-alive timeout and interval unless these values have been changed by calling the WSAIoctl function with the SIO_KEEPALIVE_VALS option. The default settings when a TCP socket is initialized sets the keep-alive timeout to 2 hours and the keep-alive interval to 1 second.
也就是说协议栈会在2小时后发送向对端发送请求包。默认情况下,此Keep-alive机制是关闭的。
Keep-alive默认下是关闭的,也就是本端与对端是除非程序主动send,是不会发送数据包(心跳包),既是,处理本端与对端的系统里的socket状态是不会变化,这里,如果对端当机(或者网线断掉),本端是无法知道对端socket已经关闭,所以本端的socket会一直的存在。
通过实验发现,客户端网线拔掉之后,此时服务端的连接依然存在。
所以,tcp只是数据的发送与接收,包括握手,断开以及rst,time_wait,close_wait 等等。
心跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着。事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很小的包,或者只包含包头的一个空包。
在TCP的机制里面,本身是存在有心跳包的机制的,也就是TCP的选项:SO_KEEPALIVE。系统默认是设置的2小时的心跳频率。但是它检查不到机器断电、网线拔出、防火墙这些断线。而且逻辑层处理断线可能也不是那么好处理。一般,如果只是用于保活还是可以的。
心跳包一般来说都是在逻辑层发送空的echo包来实现的。下一个定时器,在一定时间间隔下发送一个空包给客户端,然后客户端反馈一个同样的空包回来,服务器如果在一定时间内收不到客户端发送过来的反馈包,那就只有认定说掉线了。 其实,要判定掉线,只需要send或者recv一下,如果结如衫果为零,则为掉线。
但是,在长连接下,有可能很长一段时间都没有数据往来。理论上说,这个连接是一直保持连接的,但是实际情况中,如果中间节点出现知乎什么故障是难以知道的。更要命的是,有的节点(防火墙)会自动把一定时间之内没有数据交互的连接给断掉
。在这个时候,就需要我们的心跳包了,用于维持长连接,保活。
在获知了断线之后,服务器逻辑可能需要做一些事情,比如断线后的数据清理呀,重新连接呀……当然,这个自然是要由逻辑层根据需求去做了。
总的来说,心跳包主要也就是用于长连接的保活和断线处理。一般的应用下,判定时间在30-40秒比较不错。如果实在要求高,那就在6-9秒。
1、 客户端每隔一个时间间隔发生一个探测包给服务器
2、 客户端发包时启动一个超时定时器
3、 服务器端接收到检测包,应该回应一个包
4、 如果客户机收到服务器的应答包,则说明服务器正常,删除超时定时器
5、 如果客户端的超时定时器超时,依然没有收到应答包,则说明服务器挂了