Server端如何感知客户端的状态

如果网络拥塞严重,chatserver端如何感知客户端在线还是掉线了?
客户端主动发送close(fd),相当于TCP的四次挥手,发送FIN包,进行挥手操作,对应服务端,就有一个响应:recv=0(判断客户端掉线,下线了),
这是我们在局域网的聊天服务器里面,网络是良好的,是不会出现问题的。
但是,如果放在真实的网络环境中,这个客户端发送的FIN包有可能服务器根本收不到,因为真实的网络环境是非常非常复杂的,有可能现在我们的客户端到服务端的中间网络节点的路由器里面的报文非常多,网络拥塞非常严重,导致FIN包到达不了服务端。
TCP协议下,发送的每一个包都会去等待这个包的响应,如果没有响应,会超时重传,但是超时重传是有一定的次数,如果超过次数,TCP就会reset把socket重置了,但是还是导致这个FIN包最终还是没有到达服务端,导致这个客户端已经下线了,但是服务端并没有感知到,客户端已经自己重置了,服务端却一直以为这个客户端在线,把这个客户端所给的socketfd没有释放,相关的其他资源也没有释放,就积累越来越多的僵客户端连接。

解决方法

心跳机制!!!
比如说,服务端(listen 8080),是TCP的端口,当然,不同的协议可以绑定在同一个端口,listen 8080是专门处理业务端口,接收我们发的json数据处理业务。
UDP 8080 是心跳业务处理

可以这样设计,服务端会给每一个connect成功的客户端分配1个心跳计数:
比如说:


服务端会启动一个通用定时器(心跳计数器),比如说:超时1秒,把所有客户的心跳计数加1,每超过1秒,就加1
如果客户的心跳计数超过5了,就判断客户端已经掉线了。
每一个客户端每隔1秒都会去发了一个心跳消息,给所属的心跳计数减1
也就是说,服务端在监听1个客户端,5秒之内都没有任何心跳的话,就判断这个客户端下线了,就拆除这个客户端所有的连接以及其他资源。

客户端都是通过TCPsocket来和服务端进行通信,心跳为了不干扰我们的业务处理,专门用UDPsocket绑定8080端口,或者我们可以绑定其他的心跳端口,专门接收心跳消息,
当然,客户端发送的心跳消息要包括:userid:zhangsan1MessageType:heartbeat,服务端接收到这个心跳消息,就把zhangsan1对应的心跳计数减1,以此类推。正常,客户端的对应的心跳计数应该在-1,0,1之间不断的变化
如果客户端实时的发送心跳消息,服务端维护的这个客户端的心跳计数是不会超过5的,这样的机制可以预防网络拥塞严重,客户端的消息已经无法到达服务端了,这个消息自然也就无法到达服务端,这样一来,服务端维护的相应客户端的心跳计数,每超过1秒,没有收到心跳消息,就给心跳计数加1,加到超过5了,就认为这个客户端掉线了,说明此时的网络情况是非常非常的差,可以认为客户端不在线,因为客户端的消息过不来服务端,也有可能是发生了网络风暴,导致消息环回,到不了服务端了。

一般来说,C/S这种基于长连接的业务,都会在业务层实现心跳保持机制,用于监测对端是否依然在线

我们上面所说的是在应用层业务上自己实现的心跳机制。

在传输层,TCP协议有一个keepalive功能,保活功能。
因为TCP协议有一个缺陷,所以需要加上这个功能来弥补它的缺陷。
这个缺陷是:
TCP客户端和服务端连接成功了以后,如果客户端和服务端不交互,不发信息的话,一直连接链路,保持空闲,那么对于服务端来说,到底怎么去理解客户端的状态呢?客户端是在线,连接一直建立着,是客户端一直没有发消息,还是客户端掉线了?由于网络问题,客户端没有告诉服务端,服务端得不到通知,就像我们打电话一样,突然,都保持沉默了,你也不知道对方是掉线了还是没有说话,对于服务端来说,没有办法去感知所谓的事件创建的连接,当它里面一直沉默的话,到底这个连接还是不是有效的。
所以,TCP协议里,增加了keepalive这个功能:是在传输层添加的这个功能。和应用层没有关系。
有一些参数:

keepalive功能默认是关闭的,当我们去创建TCP的listen socket的时候,在这里,如果我们想启动keepalive功能,我们需要通过setsockopt来打开它的SO_KEEPALIVE,
它做的事情是:


net.ipv4.tcp_keepalive_time=7200:默认每隔2个小时,会发送一个空的报文段,探测对方是否在线:如果对方回复了,证明对方还在线,链路还是有效的。如果对方并没有响应,
net.ipv4.tcp_keepalive_invl=75:如果探测没有响应,延迟75秒继续发送保活的探测包。
net.ipv4.tcp_keepalive_probes=9:如果依旧是没有响应的话,最多重新探测9次,如果都没有响应,就拆除连接!!!证明这个连接确实是挂掉了。
也就是最多等待2小时+75x9 秒,如果一直没有响应,就把连接给拆除了
这个参数是可以更改的,可以把时间调小一点。

如果我们是靠TCP的keepalive来实现保活功能,在这里,如果连接中断的话,因为这是在传输层,只能把TCP的连接拆除,但是我们在应用层,一个聊天服务端检测到一个聊天客户端下线,仅仅是关闭sockfd???在我们的业务上,连接还记录着对应的connection对象存储在map表,我们都得删除啊!!!其次,因为这个keepalive是在传输层的,传输层的上面才是我们的应用层,假设我们应用层已经运行到死锁了,出问题了,已经做不了业务了,但是这只是应用层的死锁,传输层是属于操作系统内核的,内核是不会死锁的,socket在内核中依然可以和服务端发送keepalive探测包的,这就出问题了,导致服务端还是认为客户端在线的!!!

长连接的C/S是不可能依靠TCP传输层的keepalive功能做连接保活机制的。

669-Server端如何感知客户端的状态相关推荐

  1. socket下server端支持多客户端并发访问简单实现

    /* *Author: wainiwann *Source: 博客园 http://www.cnblogs.com/wainiwann *Remarks:  转载请说明出处!!! */ server端 ...

  2. TCP第三次握手失败的处理(Server端超时重传机制、RST包响应、SYN攻击)

    面试题: 在 TCP 建立连接的三次握手连接阶段,如果客户端发送的第三个ACK包丢了,那么客户端和服务端分别进行什么处理呢? 相信了解 tcp 协议的人,三次握手的过程肯定很了解了.第三次的 ack ...

  3. 完整mes代码(含客户端和server端_200行代码实现基于paxos的kv存储

    本文链接: https://blog.openacid.com/algo/paxoskv/ 前言 写完 paxos的直观解释 之后, 网友都说疗效甚好, 但是也会对这篇教程中一些环节提出疑问(有疑问说 ...

  4. 完整mes代码(含客户端和server端_Ice简介+Qt代码示例

    一.ICE是什么? ICE是ZEROC的开源通讯协议产品,它的全称是:The Internet Communications Engine,翻译为中文是互联网通讯引擎,是一个面向对象的中间件,它封装并 ...

  5. Zabbix监控学习系列(2):agent的安装与Server端添加客户端

    Zabbix监控学习系列(2) 简介描述 1. windows的客户端安装 1. 1手动安装包安装,安装过程中配置 1. 2免安装压缩包,解压后修改配置文件 2. Linux的客户端安装 3.在Zab ...

  6. Socket异步服务器,可以监控客户端的状态,功能有,文字测试,服务端向客户端传输屏幕录像(UDP传输)、监控客户端屏幕(UDP传输),抖动用户窗体、发送文件给用户、扫描客户的C盘目录。

    用VS2015工具C#语言编写了一个简单的Socket异步服务器,可以监控客户端的状态,功能有,文字测试,服务端向客户端传输屏幕录像(UDP传输).监控客户端屏幕(UDP传输),抖动用户窗体.发送文件 ...

  7. tcp 服务端如何判断客户端断开连接

    最近在做一个服务器端程序,C/S结构.功能方面比较简单就是client端与server端建立连接,然后发送消息给server.我在server端会使用专门的线程处理一条socket连接.这就涉及到一个 ...

  8. 详解zabbix安装部署(Server端篇)

    Linux下常用的系统监控软件有Nagios.Cacti.Zabbix.Monit等,这些开源的软件,可以帮助我们更好的管理机器,在第一时间内发现,并警告系统维护人员. 今天开始研究下Zabbix,使 ...

  9. zabbix 3.2.2 server端(源码包)安装部署 (一)【转】

    环境准备: 操作系统 CentOS 6.8 2.6.32-642.11.1.el6.x86_64 zabbix server 172.16.10.150 zabbix agent 172.16.10. ...

最新文章

  1. 一个爬虫的故事:爬虫兄弟要活不下去了!!!
  2. 在navicat中查看所有表的注释
  3. 什么是 Silverlight?
  4. getopt设计shell脚本选项
  5. TIME-WAIT状态
  6. jQuery特效:实现微博发布界面
  7. 【第43题】【062题库】2019年OCP认证062考试新题
  8. 微pe工具箱是微软的吗_【 微PE工具箱 】微PE工具箱(系统工具)新版下载 - U大师...
  9. 狗猫分类数据集划分详解
  10. fgo7.27服务器维护,【FGO日服】维护通知(7/12)
  11. WINDOWS蓝屏代码大全
  12. Python3使用SMTP协议发送电子邮件
  13. BZOJ3034: Heaven Cow与God Bull
  14. 7-8 约分最简分式 (15 分)
  15. 证件照怎么制作?超简单的证件照制作教程来了
  16. Web代理(HTTP代理)
  17. 【老生谈算法】matlab实现Chan算法及其验证源码——Chan算法
  18. vue props命名为啥使用kebab-case (短横线隔开式) 来命名
  19. 一个流和百亿级的表的join
  20. JS:Caesars Cipher(凯撒密码)

热门文章

  1. ARM服务器安装CentOS7.4
  2. unity中单位是米还是厘米_cm在单位里是厘米还是毫米
  3. 在Win7中将我的电脑快捷方式放入任务栏
  4. 常用的数学函数以及浮点数处理函数
  5. uni-app学习路线 - 计划
  6. c# 正则表达式 Group
  7. 以管理员身份在当前目录打开命令行窗口
  8. 模拟电子技术基础-二极管1
  9. [转帖]粤语语系分类
  10. 风格迁移1-02:Liquid Warping GAN(Impersonator)-源码模型测试-报错解决