之前有客户反馈,经常会收到客户端断开连接的提醒。影响聊天,希望能查下问题。开始我以为是用户网络波动,导致的连接断开,后来同事跟我反馈,网络正常的时候也会出现断开连接的现象,希望我查下服务器是否配置了什么,会话保持时长之类的参数。

问题重现

这个问题在c++端比较容易重现,在web端偶现,移动端却没发生过。难道是移动端一直没用户使用,所以他们也不知道?额,不能这样想,不然容易被打。一定是有人用的,可能移动端有啥不为人知的厉害操作?

问题分析

由于这个涉及的角色只有两个,server端和client端,至少目前来说,已经有两种client端都出现了问题,难道这俩端都写的有问题么?额,有一个是我写的,没弄清楚之前,不能怂。先从服务器端查起,检查相关配置,并没有发现有类似保持连接时间的配置,额。。。这就尴尬了。客户端也没有写超时自动断开的逻辑啊?几个人下午排查了半天,一直没发现问题到底是怎么回事儿。只能采用最笨的方法-抓包,然后请我们的好朋友wireshark分析下。同事在服务器端和客户端同时抓包,可是有时候就是这样,你越希望它重现,它反而越不出现。懊恼。。。

下班之前,CTO问查的如何了。大眼瞪小眼,不敢定结论。

他说他看下,第二天中午,cto拉我们去说这个问题,他找到原因了。

他给我们看异常断开连接前的包,发现断开连接之前会发两个包,每个包间隔是2s,上一条消息的间隔时间是20s,多次异常断开都是如此。这应该不是巧合,这个包来自服务器端,这说明服务器发完这两个包之后,没有得到响应,就把客户端断开了连接。这个实际上是服务器的tcp连接的keeplive机制,当服务器检测到一个socket端长时间不活动的时候,就会发送一个探测包检测client端是否还在,而当client端收到不回应的时候,会关闭连接,回收资源。linux内核跟这个相关的参数有三个:
tcp_keepalive_time(开启keepalive的闲置时长)
tcp_keepalive_intvl(keepalive探测包的发送间隔)
tcp_keepalive_probes (如果对方不予应答,探测包的发送次数)

那是不是这三个内核参数的配置问题呢?检查当前配置:

root@xxx:/# sysctl -a | grep keep
net.ipv4.tcp_keepalive_intvl = 2
net.ipv4.tcp_keepalive_probes = 2
net.ipv4.tcp_keepalive_time = 20

果然,跟猜想一样,问题出自这个配置,初始化服务器的时候,会有脚本自动调优。加上应用层上编写代码时,并没有设置此参数,覆盖系统的设置。所以导致了总是莫名其妙的自己断开。

真相大白,对cto的崇拜又多了几分,总能在众人迷惑的时候,站出来当指明灯。

解决方案:
1. 应用层增加socket保活参数配置,覆盖系统配置(完美)
2. 直接修改系统配置文件/etc/sysctl.conf,应用层增加心跳机制,空闲状态时,每隔19s发送一个心跳包过去(实际采用)。

顺便说一下,之前移动端确实没有发生断开连接的异常情况,是因为移动端的开发主动加过保活机制,赞一个。

附录:
tcp长连接和保活时间(keepalive)
keeplive详解

socket 莫名其妙的断开连接?相关推荐

  1. C#socket通信时,怎样判断socket双方是否断开连接

    我在Server端new了一个socket,然后bind,开了一个线程来accept前来连接的client,每接到一个client前来连接就新开一个线程和它进行通信. 我把Server端得到的sock ...

  2. [C#]手把手教你打造Socket的TCP通讯连接(三)

    上一篇中,我们编写了SocketHandler处理Socket的IO. 现在我们只剩下服务器端了. 服务器端包含两个类,一个TCPListener,一个TCPListenerClient. TCPLi ...

  3. C语言socket connect()函数(初始化套接字上的连接)(未完)(如何测试socket是否已经断开,如何判断socket是否断开)

    参考文章:C网络编程socket之connect函数 需研究下这个函数超时多久才返回... 文章目录 项目中注释解释 man 2 文档解释 关于上面man 2 手册中所提到的connect()案例,在 ...

  4. Python使用socket实现局域网传输数据(附加json数据传输及解析)以及判断socket是否断开连接

    1 本机实现服务端和客户端的通信并传输字符串数据 1.1 服务端 # -*- coding: utf-8 -*- import socketserver = socket.socket() serve ...

  5. c#endread怎么打印出来_c# – Socket.EndRead 0字节意味着断开连接?

    我想知道在c#中的异步套接字中,在EndRead调用中接收0个字节意味着服务器实际上已经断开了我们的连接吗? 我看到的很多例子都表明情况就是这样,但我收到的断线频率要高得多. 这段代码是否正确?或者e ...

  6. c语言linux TCP长连接 socket收发范例 断开自动重连

    原文链接:https://blog.csdn.net/chenhao0568/article/details/103420615 c语言linux TCP长连接 socket收发范例 断开自动重连 改 ...

  7. JAVA 判断Socket 远程端是否断开连接

    JAVA 判断Socket 远程端是否断开连接 最近在做项目的时候,遇到这样一个问题,如何判断 Socket 远程端连接是否关闭,如果关闭的话,就要重建连接Socket的类提供了一些已经封装好的方法, ...

  8. java socket 断开连接_Socket断开不报错(Java)

    网上看了很多关于Socket的Demo,用起来挺好用也简单,不过都在断开连接时,都没有做好相关处理,导致每次主动断开时,会报错 如: java.net.SocketException: Socket ...

  9. 被调用的对象已与其客户端断开连接 win10_【完整案例】基于Socket开发TCP传输客户端...

    1 程序界面设计 TCP客户端在上位机开发中应用很广,大多数情况下,上位机软件都是作为一个TCP客户端来与PLC或其他服务器进行通信的.TCP客户端的主要功能就是连接服务器.发送数据.接收数据.断开连 ...

最新文章

  1. python 获取窗口句柄_Python文件读写最详细的讲解
  2. 训练数据集如何划分验证测试集?train/test(val/dev) set和交叉验证(cross validation)
  3. 【Android RTMP】音频数据采集编码 ( FAAC 头文件与静态库拷贝到 AS | CMakeList.txt 配置 FAAC | AudioRecord 音频采样 PCM 格式 )
  4. python 一些方法的时间测试
  5. php 字符串去html,PHP strip_tags() 去字符串中的 HTML、XML 以及 PHP 标签的函数
  6. php二进制安全的含义
  7. 知识图谱最新论文清单,高阶炼丹师为你逐一解读
  8. java 生成.sh文件,Java 生成Bat或SH文件,调用Sqlldr安插数据到Oracle
  9. python3----列表
  10. Linux Shell 从入门到删除根目录跑路指南
  11. 9.Excel数据透视表
  12. 「ROI 2017 Day 2」反物质(单调队列优化dp)
  13. 动态规划 —— 背包问题 P07 —— 有依赖背包
  14. Nginx基本数据结构之ngx_list_t
  15. linux常用指令学习记录
  16. v5服务器装系统,小白必学:宏基V5-591G内存、固态、装系统教程!
  17. SpringBoot 无法捕获 maximum upload size exceeded
  18. 分布式架构中的八大谬误
  19. c盘python27文件夹可以删除嘛_C盘的哪些文件夹可以删
  20. ios点击推送闪退_升级iOS14.1之后,我的6S崩溃了|ios|ios系统|手机|闪退

热门文章

  1. ECSHOP+wamp
  2. 5G宏基站的形态5G基站长什么样?
  3. HTC终端4G网络附着问题
  4. kettle入门介绍
  5. 法规标准-ISO 21202标准解读
  6. 轩辕剑龙舞云山如何在电脑上玩 轩辕剑龙舞云山模拟器教程
  7. 腾讯安全被列为全球大型威胁情报厂商
  8. 浙江移动服务器维护升级时间,中国移动终于“良心了”!10年不换号的老用户,将获得这3大特权...
  9. Robbin要发财了,我呢?爱就爱。。。爱就爱。。。
  10. OBS 直播多路推流