概述
引言
断开的通知,然后进行必要的处理;但如果任意一方发生所谓的“非优雅断开”,如:意外崩溃、死机、
拔掉网线或路由器故障时,另一方无法得知TCP 连接已经失效,除非继续在此连接上不断地发送数据,
经过若干时间后导致错误返回。但在很多时候,更希望服务器端和客户端都能及时有效地检测到网络连
接的非正常断开,然后完成一些必要的清理工作并把错误报告给用户。
告诉对方网络通信是否正常或已断开。
1. 心跳原理
中,链路的连通只在连接双方记录状态,物理通道内不存在一个实际的连接链路,通信的双方只能定时
发送简单的信息给另一方,并根据超时来判断线路是长时间空闲还是已断开。这种通过每隔一定时间发
送一个固定信息给对方,对方收到后回复一个固定信息,告诉对方“我还在”的方式非常类似于心跳,所
发送的这种简单信息就称为“心跳包”。
心跳包的发送,通常有两种技术:一种是由用户在应用层实现的心跳包,另一种是由TCP 协议层提
供的KeepAlive 。
2. 应用层自己实现的心跳包
向客户端发送一个短小精悍的数据包,然后启动一个低级别的线程,在该线程中不断检测客户端的回应,
如果在一定时间内没有收到客户端的回应,即认为客户端已经掉线;同样,如果客户端在一定时间内没
有收到服务器的心跳包,则认为连接不可用。
3. TCP 的KeepAlive 保活机制
且稍显复杂,而利用TCP/IP 协议层为内置的KeepAlive 功能来实现心跳功能则简单得多。
不论是服务端还是客户端,一方开启KeepAlive 功能后,就会自动在规定时间内向对方发送心跳包,
而另一方在收到心跳包后就会自动回复,以告诉对方我仍然在线。
因为开启KeepAlive 功能需要消耗额外的宽带和流量,所以TCP 协议层默认并不开启KeepAlive 功
能,尽管这微不足道,但在按流量计费的环境下增加了费用,另一方面,KeepAlive 设置不合理时可能会
因为短暂的网络波动而断开健康的TCP 连接。并且,默认的KeepAlive 超时需要7,200,000 MilliSeconds,
即2 小时,探测次数为5 次。对于很多服务端应用程序来说,2 小时的空闲时间太长。因此,我们需要手
工开启KeepAlive 功能并设置合理的KeepAlive 参数。
目前主要有三种方法来实现用户掉线检测:SO_KEEPALIVE ,SIO_KEEPALIVE_VALS 和Heart-Beat线程。
下面我就上面的三种方法来做一下介绍。
(1)SO_KEEPALIVE 机制
(2)SIO_KEEPALIVE_VALS 机制
(3)Heart-Beat线程
有开发网络应用经历的人都知道,网络中的接收和发送数据都是使用WINDOWS中的SOCKET进行实现。但是如果此套接字已经断开,那发送数据和接收数据的时候就一定会有问题。可是如何判断这个套接字是否还可以使用呢?
有人一定想到使用Send函数中的返回结果来进行判断。如果返回的长度和自己发送出去的长度一致,那就说明这个套接字是可用的,否则此套接字一定出现了问题。但是我们并不是无时无刻的发送数据呀。如何解决呢?
其实TCP中已经为我们实现了一个叫做心跳的机制。如果你设置了心跳,那TCP就会在一定的时间(比如你设置的是3秒钟)内发送你设置的次数的心跳(比如说2次),并且此信息不会影响你自己定义的协议。
在VC中实现心跳的例子很多,可是在DLEPHI中一直没有相应的代码。下面我是我使用DELPHI编写的关于心跳的代码(以IOCP为例),希望对大家有帮助。
定义心跳常量
const
var
实现代码是在Acceptsc:= WSAAccept(Listensc, nil, nil, nil, 0);代码的后面加入:
inKeepAlive.keepalivetime:=3000;
如果加入以上的代码以后,系统会每3秒中加入一次的心跳。并且如果客户端断线以后(网线断),函数GetQueuedCompletionStatu
if (GetQueuedCompletionStatu
continue;
以上就是我使用心跳的方法,此方法我已经在我的网络游戏中使用。情况稳定!
网络程序容易出现死连接,连接以经无效了,但是连接状态还是ESTABLISHED状态,如何识别连接以经失效就需要使用
------------------------------------------------------------------------------------------------------
下面是方法2的一段可用代码(经过僧僧鞋子 测试 可用!!!)
---------------------------------------------------------------------------------------
保活机制(心跳机制)下面是一个代码效果还是挺好的,感谢cooldiyer的资料
typedef struct STcpKeepAlive2
{
}TCP_KEEP_ALIVE2;
VOID SetKeepLive(SOCKET m_Socket)
{
}
其中SIO_KEEPALIVE_VALS的值定义为:
注:SIO_KEEPALIVE_VALS
最后
以上就是还单身百合为你收集整理的基于Windows Socket 的网络通信中的心跳机制原理的全部内容,希望文章能够帮你解决基于Windows Socket 的网络通信中的心跳机制原理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复