TCP之心跳包实现思路
说起网络应用编程,想到最多的就是聊天类的软件。当然,在这类软件中,一般都会有一个用户掉线检测功能。今天我们就通过使用自定义的HeartBeat方式来检测用户的掉线情况。
心跳包实现思路
我们采用的思路是:客户端连接上服务端以后,服务端维护一个在线用户字典,客户端每隔一段时间,向服务器发送一个心跳包,服务器接收到包以后,字典数据的值都会更新为0;一旦服务端超过规定时间没有接收到客户端发来的包,字典数据将会递增加一,当字典数据的值累计大于等于三,则视为掉线。
代码逻辑
客户端每隔一段时间,发送一个心跳包:
#region 心跳Timer计数事件
private void heartbeatTimer_Tick(object sender, EventArgs e)
{
currentCount++;
if (currentCount == heartbeatCount)
{
txtMessage.Append("开始发送心跳包");
MessageEntity entity = new MessageEntity();
entity.MessageType = MessagePicks.Heartbeat;
entity.NickName = loginName; WriteToStream(entity);
currentCount = ;
}
}
#endregion
在服务端,会开启一个定时器,定时将userOnLineCounter中的值递增加一。如果此时收到客户端的心跳包,则将userOnLineCounter中的值重置。
private void heartbeatTimer_Tick(object sender, EventArgs e)
{
tickCountInStep++;
if (tickCountInStep == tickCount)
{
if (userCollection.Count > )
{
//计数器自动递增
expiryCountInStep++;
foreach (User user in userLists)
{
userOnLineCounter[user]++;
}
//连续监测三次之后,开始监测集合中的掉线情况
if (expiryCountInStep == expiryCount)
{
//寻找集合中“掉线”的用户
var disconnectedUsers = userOnLineCounter.Where(p => p.Value >= ).ToList();
foreach (var disconnectedUser in disconnectedUsers)
{
txtLog.Append("用户" + disconnectedUser.Key.name + "掉线!"); //删除集合中被视为掉线的用户
userLists.Remove(disconnectedUser.Key);
userOnLineCounter.Remove(disconnectedUser.Key); //开始广播发送掉线用户
MessageEntity entity = new MessageEntity();
entity.MessageType = MessagePicks.OffLine;
EndPoint curOfflineUserEP = disconnectedUser.Key.client.Client.RemoteEndPoint;
string userName = disconnectedUser.Key.name;
entity.MessageContentEx.Add(curOfflineUserEP, userName); ObjectInversion inversion = new ObjectInversion();
byte[] byteArr = inversion.SerializeTo((object)entity); try
{
foreach (User user in userLists)
{
user.writer.Write(byteArr);
user.writer.Flush();
}
}
catch { }
}
expiryCountInStep = ;
}
}
tickCountInStep = ;
}
}
}
收到客户端心跳包,自动重置计数器。
case MessagePicks.Heartbeat:
txtLog.Append("收到客户端" + entity.NickName + "的心跳回应包.");
if (userOnLineCounter.ContainsKey(user))
userOnLineCounter[user] = ;
else
userOnLineCounter.Add(user, );
break;
效果图
(图1:三个客户端连接一个服务器)
(图2:用户“上善若水”掉线)
(图3:用户“古道热肠”掉线)
程序暂时还未完全完成,有需要的可以参考下。当然也期待大家的各种思路。
代码很丑,期望大家指点下重构的方法。
源码下载
=====================2014年9月24日重构版本=======================
用户实体内部通过维护一个timer计数器,实现心跳检测,心跳超时功能。
TCP之心跳包实现思路的更多相关文章
- Tcp之心跳包
Tcp之心跳包 心跳包 跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着. 事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很 ...
- TCP socket心跳包示例程序
在做游戏开发时,经常需要在应用层实现自己的心跳机制,即定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性. 在TCP socket心跳机制中,心跳包可以由服务器发送给客户端 ...
- Socket之心跳包实现思路
由于最近要做一个客户端,但是要求有一个掉线检测的功能,下面让我们看看使用自定义的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:用户数据报协议:主要用在实时性要求比较高的以及对质量相对较弱的地方.但是面对现在高质量的线路不会容易丢包,除 ...
随机推荐
- cornerstone 使用
svn 使用方法 Check Out 下载的文件会与源文件产生一个working copy与源文件关联
- Unix系统中,两个进程间的通信
进程之间通常需要进行数据的传输或者共享资源等,因此进程间需要通讯. 可以通过管道,信号,消息队列,共享内存,信号量和套接字等方式 FIFO表示命名管道,这种管道的操作是基于先进先出原理. PIPE 表 ...
- 大家一起和snailren学java-(二)一切都是对象
“今天是周末,虽然外面阳光晴好,但是作为一名单身狗,还是除了寝室,就只有图书馆了.Anyway,既然没有对象,那我们就在java中找对象吧,哈哈.没有对象的人,看一切,都是对象!” 在面向对象程序设计 ...
- python数据结构-列表-建立/索引/反转
- 使用百度出品的 uaredirect.js 来判断客户端是否为手机
目前一般的网站都分成了PC版和手机版,当访问的浏览器是来自PC版时,则让其访问PC版的网页,当访问的浏览器是来自手机时,则让其跳转到手机版的地址.百度的uaredirect.js 就是一个小小的工具, ...
- 问题解决——在STL的queue中使用自定义类
本文原创,转载请保证文章的完整性,并显要的注明出处. 本文链接:http://blog.csdn.net/wlsgzl/article/details/38843513 平时很少用STL,就算用,也基 ...
- Github学习之路-小试牛刀,练习Git 的基本操作
一.下子windows客户端. Git 客户端下载地址:http://msysgit.github.io/ 二.打开Git Bash 命令行操作界面. 安装完成后,在开始菜单里找到“Git”-> ...
- Android开发中 .9.png格式图形设计:
Android .9.png设计 宿舍大神在做android项目,有幸得知.9.png的图形格式. 不知道大家是否注意过聊天气泡和锁屏时随着你文字的增多和你的滑动而跟着变化并且分辨率没有变低的图形?是 ...
- C语言变参问题
C++中有函数重载这种方法,以供我们调用时要可以不确定实参的个数,其实 C 语言也可以,而且更高明! 我们在stdio.h 中可以看到 printf() 函数的原型: int printf(char ...
- java coder的水平
写java写了也12年了,不决的自己是高手,但是也体会了一些变化.总的来说,Java可以分成几个层次: 首先是需求理解层次,这个层次的coder能理解需求,把需求转化成代码: 第二个层次是单测,能够对 ...