Socket心跳包机制

Socket心跳包机制

分类: C++ MFC/C#/Qt TCP/IP/UDP等网络编程2012-12-10 20:42 20431人阅读 评论(4) 收藏 举报

心跳包的发送,通常有两种技术
方法1:应用层自己实现的心跳包 
由应用程序自己发送心跳包来检测连接是否正常,大致的方法是:服务器在一个 Timer事件中定时 向客户端发送一个短小精悍的数据包,然后启动一个低级别的线程,在该线程中不断检测客户端的回应, 如果在一定时间内没有收到客户端的回应,即认为客户端已经掉线;同样,如果客户端在一定时间内没 有收到服务器的心跳包,则认为连接不可用。

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

心跳包机制

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

心跳检测步骤:
1客户端每隔一个时间间隔发生一个探测包给服务器
2客户端发包时启动一个超时定时器
3服务器端接收到检测包,应该回应一个包
4如果客户机收到服务器的应答包,则说明服务器正常,删除超时定时器
5如果客户端的超时定时器超时,依然没有收到应答包,则说明服务器挂了
转自:http://blog.sina.com.cn/s/blog_a459dcf5010153m5.html

根据上面的介绍我们可以知道对端以一种非优雅的方式断开连接的时候,我们可以设置SO_KEEPALIVE属性使得我们在2小时以后发现对方的TCP连接是否依然存在。
具体操作:
    //设置KeepAlive     
   1、 BOOL   bKeepAlive   =   TRUE;     
    int nRet=::setsockopt(sockClient,SOL_SOCKET,SO_KEEPALIVE,(char*)&bKeepAlive,sizeof(bKeepAlive));     
    if(nRet!=0)    
    {     
        AfxMessageBox("出错"); 
        return   ;
    }     
    
   2、感觉两小时时间太长可以自行设定方法1 
//设置KeepAlive检测时间和次数     
    tcp_keepalive    inKeepAlive   =   {0};   //输入参数     
    unsigned   long   ulInLen   =   sizeof(tcp_keepalive );         
    
    tcp_keepalive    outKeepAlive   =   {0};   //输出参数     
    unsigned   long   ulOutLen   =   sizeof(tcp_keepalive );         
    
    unsigned   long   ulBytesReturn   =   0;     
    
    //设置socket的keep   alive为10秒,并且发送次数为3次     
    inKeepAlive.onoff   =   1;       
    inKeepAlive.keepaliveinterval   =   4000;   //两次KeepAlive探测间的时间间隔     
    inKeepAlive.keepalivetime   =   1000;   //开始首次KeepAlive探测前的TCP空闭时间     
    
    nRet=WSAIoctl(sockClient,       
        SIO_KEEPALIVE_VALS,     
        (LPVOID)&inKeepAlive,     
        ulInLen,     
        (LPVOID)&outKeepAlive,     
        ulOutLen,     
        &ulBytesReturn,     
        NULL,     
        NULL);     
    if(SOCKET_ERROR   ==   nRet)     
    {     
        AfxMessageBox("出错");
        return;    
    }   
3、感觉两小时时间太长可以自行设定方法2
因此我们可以得到
    int                 keepIdle = 6;
    int                 keepInterval = 5;
    int                 keepCount = 3;
    Setsockopt(listenfd, SOL_TCP, TCP_KEEPIDLE, (void *)&keepIdle, sizeof(keepIdle));
    Setsockopt(listenfd, SOL_TCP,TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
    Setsockopt(listenfd,SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));

详见:http://blog.csdn.net/gavin1203/article/details/5290609
setsockopt的操作,详见:http://www.cnblogs.com/hateislove214/archive/2010/11/05/1869886.html

时间: 2024-10-10 03:05:00

Socket心跳包机制的相关文章

socket 心跳包机制

如果需要在项目中像QQ微信一样做到即时通讯,必须使用socket通讯,本人也是刚学习,分享一下,有什么不对的地方希望大家指正 ios原生的socket用起来不是很直观,所以我用的是AsyncSocket这个第三方库,对socket的封装比较好,只是好像没有带外传输(out—of-band) 如果你的服务器需要发送带外数据,可能得想下别的办法 环境 下载AsyncSockethttps://github.com/robbiehanson/CocoaAsyncSocket类库,将RunLoop文件夹

心跳包机制原理

心跳包的发送,通常有两种技术 方法1:应用层自己实现的心跳包 由应用程序自己发送心跳包来检测连接是否正常,大致的方法是:服务器在一个 Timer事件中定时 向客户端发送一个短小精悍的数据包,然后启动一个低级别的线程,在该线程中不断检测客户端的回应, 如果在一定时间内没有收到客户端的回应,即认为客户端已经掉线:同样,如果客户端在一定时间内没 有收到服务器的心跳包,则认为连接不可用. 方法2:TCP的KeepAlive保活机制 因为要考虑到一个服务器通常会连接多个客户端,因此由用户在应用层自己实现心

【转载】TCP socket心跳包示例程序

在做游戏开发时,经常需要在应用层实现自己的心跳机制,即定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性. 在TCP socket心跳机制中,心跳包可以由服务器发送给客户端,也可以由客户端发送给服务器,不过比较起来,前者开销可能更大.-- 这里实现的是由客户端给服务器发送心跳包,基本思路是: 1) 服务器为每个客户端保存了IP和计数器count,即map<fd, pair<ip, count>>.服务端主线程采用 select 实现多路IO复用,监听新连

心跳包机制

跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着.事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很小的包,或者只包含包头的一个空包. 在TCP的机制里面,本身是存在有心跳包的机制的,也就是TCP的选项:SO_KEEPALIVE.系统默认是设置的2小时的心跳频率.但是它检查不到机器断电.网线拔出.防火墙这些断线.而且逻辑层处理断线可能也不是那么好处理.一般,如果只是用于保活还是可以的. 心跳包一般来说都是在逻辑层发送空的e

web socket 心跳包的实现方案

web socket 心跳包的实现方案05/30/2010 现在网络环境错综复杂,socket心跳包是获得健康强壮的连接的有效解决方案,今天,我们就在web socket中实现心跳包方案,是的,尽管我们只是做一个简单的聊天室,但我们让他稳定可靠一些一点也没有错. 我的心跳包方案很是简单,原理就是间隔发送心跳包数据给服务器,服务器在一定时间内发回心跳包响应,对比超时限定,如果超过设定的超时时间,则认为当前与服务器的websocket连接已经断开,关闭当前web socket连接,善后处理,例如重新

[转] Socket心跳包异常检测的C语言实现,服务器与客户端代码案例

转载自:zxh2075的专栏 在Socket心跳机制中,心跳包可以由服务器发送给客户端,也可以由客户端发送给服务器,不过比较起来,前者开销可能较大.本文实现的是由客户端给服务器发送心跳包,服务器不必返回应答包,而是通过判断客户在线会话记录中的计数标志值来实现心跳异常的检测,以此决定客户端是否已经断开连接以及删除其在线会话记录. 基本思路: ①客户端定时给服务器发送心跳包(案例中定时时间为3秒): ②服务器创建一个心跳检测的线程,线程中每隔3秒对用户在线会话记录中的计数器进行加1操作(初始值为0)

心跳包机制整理汇总

[背景] 现需要实现这样的功能:有多个客户端连着同一个服务器.服务器和客户端之间需要“互相”知道彼此的连接状态.比如在某一时刻,服务器需要知道当前有多少个客户端正在和其通信:某一个时刻,某个客户端需要知道自己是否和服务器保持连接.如果在某一时刻,一个客户端关闭了,服务端应能及时感觉到:同样,如果服务端被关闭,所有的客户端应能及时感觉到,并作出一些反应. 1.从程序的角度看待TCP掉线 TCP掉线的原因可能多种多样.不一而足,比如,客人的电脑突然断电.OS崩溃.路由器重启.网线接触不良.因为P2P

长连接和心跳包

第一种设置:通过设置socket的keepalive属性#include    "/usr/include/linux/tcp.h"#include "/usr/include/linux/socket.h"////KeepAlive实现,单位秒//下面代码要求有ACE,如果没有包含ACE,则请把用到的ACE函数改成linux相应的接口int keepAlive = 1;//设定KeepAliveint keepIdle = 5;//开始首次KeepAlive探测前

TCP心跳包

所谓的心跳包就是客户端定时放送简单的信息给服务器端,告诉它我还在而已.代码就是每 隔几分钟发送一个固定信息给服务器端,服务器端回复一个固定信息.如果服务器端几分钟后没有收到客户端信息则视客户端断开.比如有些通信软件长时间不适 用,要想知道它的状态是在线还是离线,就需要心跳包,定时发包收包. 心跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活在.事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很小的包,活着只包含包头的一个空包