TCP 连接,一端断电和进程崩溃有什么区别?

TCP 连接,一端断电和进程崩溃有什么区别?

  • 前言
  • 主机崩溃
  • 进程崩溃
  • 有数据传输的场景
    • 客户端主机宕机,又迅速重启
    • 客户端主机宕机,一直没有重启
  • 总结

前言

有的小伙伴在面试腾讯的时候,遇到了这么个问题:

在这里插入图片描述

这个属于 TCP 异常断开连接的场景,这部分内容在我的「图解网络」还没有详细介绍过,这次就乘着这次机会补一补。

在这里插入图片描述

这个问题有几个关键词:

  • 没有开启 keepalive;
  • 一直没有数据交互;
  • 进程崩溃;
  • 主机崩溃;

我们先来认识认识什么是 TCP keepalive 呢?

这东西其实就是 TCP 的保活机制,它的工作原理我之前的文章写过,这里就直接贴下以前的内容。

在这里插入图片描述

如果两端的 TCP 连接一直没有数据交互,达到了触发 TCP 保活机制的条件,那么内核里的 TCP 协议栈就会发送探测报文。

  • 如果对端程序是正常工作的。当 TCP 保活的探测报文发送给对端, 对端会正常响应,这样 TCP 保活时间会被重置,等待下一个 TCP 保活时间的到来。
  • 如果对端主机崩溃,或对端由于其他原因导致报文不可达。当 TCP 保活的探测报文发送给对端后,石沉大海,没有响应,连续几次,达到保活探测次数后,TCP 会报告该 TCP 连接已经死亡。

所以,TCP 保活机制可以在双方没有数据交互的情况,通过探测报文,来确定对方的 TCP 连接是否存活。

在这里插入图片描述

注意,应用程序若想使用 TCP 保活机制需要通过 socket 接口设置 SO_KEEPALIVE 选项才能够生效,如果没有设置,那么就无法使用 TCP 保活机制。

主机崩溃

知道了 TCP keepalive 作用,我们再回过头看题目中的「主机崩溃」这种情况。

在没有开启 TCP keepalive,且双方一直没有数据交互的情况下,如果客户端的「主机崩溃」了,会发生什么。

客户端主机崩溃了,服务端是无法感知到的,在加上服务端没有开启 TCP keepalive,又没有数据交互的情况下,服务端的 TCP 连接将会一直处于 ESTABLISHED 连接状态,直到服务端重启进程。

所以,我们可以得知一个点,在没有使用 TCP 保活机制且双方不传输数据的情况下,一方的 TCP 连接处在 ESTABLISHED 状态,并不代表另一方的连接还一定正常。

进程崩溃

那题目中的「进程崩溃」的情况呢?

TCP 的连接信息是由内核维护的,所以当服务端的进程崩溃后,内核需要回收该进程的所有 TCP 连接资源,于是内核会发送第一次挥手 FIN 报文,后续的挥手过程也都是在内核完成,并不需要进程的参与,所以即使服务端的进程退出了,还是能与客户端完成 TCP四次挥手的过程。

我自己做了实验,使用 kill -9 来模拟进程崩溃的情况,发现在 kill 掉进程后,服务端会发送 FIN 报文,与客户端进行四次挥手。

所以,即使没有开启 TCP keepalive,且双方也没有数据交互的情况下,如果其中一方的进程发生了崩溃,这个过程操作系统是可以感知的到的,于是就会发送 FIN 报文给对方,然后与对方进行 TCP 四次挥手。

在这里插入图片描述

有数据传输的场景

以上就是对这个面试题的回答,接下来我们看看在「有数据传输」的场景下的一些异常情况:

  • 第一种,客户端主机宕机,又迅速重启,会发生什么?
  • 第二种,客户端主机宕机,一直没有重启,会发生什么?

客户端主机宕机,又迅速重启

在客户端主机宕机后,服务端向客户端发送的报文会得不到任何的响应,在一定时长后,服务端就会触发超时重传机制,重传未得到响应的报文。

服务端重传报文的过程中,客户端主机重启完成后,客户端的内核就会接收重传的报文,然后根据报文的信息传递给对应的进程:

  • 如果客户端主机上没有进程绑定该 TCP 报文的目标端口号,那么客户端内核就会回复 RST 报文,重置该 TCP 连接;
  • 如果客户端主机上有进程绑定该 TCP 报文的目标端口号,由于客户端主机重启后,之前的 TCP 连接的数据结构已经丢失了,客户端内核里协议栈会发现找不到该 TCP 连接的 socket 结构体,于是就会回复 RST 报文,重置该 TCP 连接。

所以,只要有一方重启完成后,收到之前 TCP 连接的报文,都会回复 RST 报文,以断开连接。

客户端主机宕机,一直没有重启

这种情况,服务端超时重传报文的次数达到一定阈值后,内核就会判定出该 TCP 有问题,然后通过 Socket 接口告诉应用程序该 TCP 连接出问题了,于是服务端的 TCP 连接就会断开。

在这里插入图片描述

那 TCP 的数据报文具体重传几次呢?

在 Linux 系统中,提供一个叫 tcp_retries2 配置项,默认值是 15,如下图:

在这里插入图片描述

这个内核参数是控制,在 TCP 连接建立的情况下,超时重传的最大次数。

不过 tcp_retries2 设置了 15 次,并不代表 TCP 超时重传了 15 次才会通知应用程序终止该 TCP 连接,内核会根据 tcp_retries2 设置的值,计算出一个 timeout(如果 tcp_retries2 =15,那么计算得到的 timeout = 924600 ms),如果重传间隔超过这个 timeout,则认为超过了阈值,就会停止重传,然后就会断开 TCP 连接。

在发生超时重传的过程中,每一轮的超时时间(RTO)都是倍数增长的,比如如果第一轮 RTO 是 200 毫秒,那么第二轮 RTO 是 400 毫秒,第三轮 RTO 是 800 毫秒,以此类推。

而 RTO 是基于 RTT(一个包的往返时间) 来计算的,如果 RTT 较大,那么计算出来的 RTO 就越大,那么经过几轮重传后,很快就达到了上面的 timeout 值了。

举个例子,如果 tcp_retries2 =15,那么计算得到的 timeout = 924600 ms,如果重传总间隔时长达到了 timeout 就会停止重传,然后就会断开 TCP 连接:

  • 如果 RTT 比较小,那么 RTO 初始值就约等于下限 200ms,也就是第一轮的超时时间是 200 毫秒,由于 timeout 总时长是 924600 ms,表现出来的现象刚好就是重传了 15 次,超过了 timeout 值,从而断开 TCP 连接
  • 如果 RTT 比较大,假设 RTO 初始值计算得到的是 1000 ms,也就是第一轮的超时时间是 1 秒,那么根本不需要重传 15 次,重传总间隔就会超过 924600 ms。

最小 RTO 和最大 RTO 是在 Linux 内核中定义好了:

#define TCP_RTO_MAX ((unsigned)(120*HZ))
#define TCP_RTO_MIN ((unsigned)(HZ/5))

Linux 2.6+ 使用 1000 毫秒的 HZ,因此TCP_RTO_MIN约为 200 毫秒,TCP_RTO_MAX约为 120 秒。

如果tcp_retries设置为15,且 RTT 比较小,那么 RTO 初始值就约等于下限 200ms,这意味着它需要 924.6 秒才能将断开的 TCP 连接通知给上层(即应用程序),每一轮的 RTO 增长关系如下表格:

在这里插入图片描述

总结

如果「客户端进程崩溃」,客户端的进程在发生崩溃的时候,内核会发送 FIN 报文,与服务端进行四次挥手。

但是,「客户端主机宕机」,那么是不会发生四次挥手的,具体后续会发生什么?还要看服务端会不会发送数据?

  • 如果服务端会发送数据,由于客户端已经不存在,收不到数据报文的响应报文,服务端的数据报文会超时重传,当重传总间隔时长达到一定阈值(内核会根据 tcp_retries2 设置的值计算出一个阈值)后,会断开 TCP 连接;
  • 如果服务端一直不会发送数据,再看服务端有没有开启 TCP keepalive 机制?
    • 如果有开启,服务端在一段时间没有进行数据交互时,会触发 TCP keepalive 机制,探测对方是否存在,如果探测到对方已经消亡,则会断开自身的 TCP 连接;
    • 如果没有开启,服务端的 TCP 连接会一直存在,并且一直保持在 ESTABLISHED 状态。

最后说句,TCP 牛逼,啥异常都考虑到了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/835063.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java入门基础学习笔记11——关键字和标识符

1、关键字 关键字是java中已经被赋予特定意义的,有特殊作用的一些单词,不可以把这些单词作为标识符来使用。 注意:关键字是java用了的,我们就不能用来作为:类名、变量名、否则会报错。 标识符: 标识符就是…

机器学习的一些知识点分享

下面数据集中,第2个样本的第4个属性的值是( )。 A 52 B 男 C 50 D 49 本题得分: 2分 正确答案: D 2.单选题 (2分) 10-折交叉验证是把数据集分成( )个子集,将其中&#xff…

EmploLeaks:一款针对企业安全的组织员工信息收集OSINT工具

关于EmploLeaks EmploLeaks是一款针对企业安全的组织员工信息收集OSINT工具,在该工具的帮助下,企业内部的安全人员和管理员可以有效地收集组织内员工的各种信息,并以此来判断组织内部的网络安全态势。 工作机制 首先,该工具会在…

MySQL库操作 表操作【详细解析】

MySQL MySQL是一个数据库软件 mysql mysql是一个“客户端—服务器”结构的软件 (1) a.客户端:主动发起请求的一方(Client) b.服务器:被动接收请求的一方(Server) 客户端和服务器之间通过网络 进行通信 (…

【软件测试】3.开发模型

目录 1.常见的开发模型 1.1瀑布模型 1.2螺旋模型 1.3增量模型和迭代模型 1.4敏捷模型 1.4.1特点: 1.5Scrum模型(三个角色和五个重要会议) 1.5.1三个角色: 1.5.2Scrum工作流程(五个会议) 1.6测试模…

移动应用开发实验四AlarmManager实现闹钟提醒

实验目的和要求 在Android Studio中,通过AlarmManager实现闹钟提醒。 点击“SET ALARM”后,采用Toast方式提示用于设定的闹钟成功,并包含设定的闹钟启用时间。 当闹钟生效时,采用AlertDialog实现闹钟题型,并通过Ale…

2023盘古石杯晋级赛 apk分析 WP

1. 涉案应用刷刷樂的签名序列号是[答案:123ca12a] 2. 涉案应用刷刷樂是否包含读取短信权限 无 3. 涉案应用刷刷樂打包封装的调证ID值是[答案:123ca12a] 4. 涉案应用刷刷樂服务器地址域名是[答案:axa.baidun.com] 代理模式抓个包 5. 涉案应用…

UE4 3D文字自动换行

效果:3D文字超过5位自动换行 1.随意输入一段字符串测试,创建string临时变量,用于迭代存储字符串 2.当字符串遍历至第“换行长度”(我这里是5)位时,附加一次空行

创新指南|将会话式AI聊天机器人纳入PLG增长战略

想象一个繁荣的数字城市广场,志同道合的人们在这里分享他们的激情、经验和知识。想象一个将房东与旅行者、顾客与司机、人们与他们喜爱的品牌无缝连接起来的平台。在这个世界里,用户交流促进增长,社区成为推动力。 如果您的应用程序天生不符…

P8802 [蓝桥杯 2022 国 B] 出差

P8802 [蓝桥杯 2022 国 B] 出差 分析 很明显:单源最短路径 没有负权边 dijkstra 1.存图 2.准备两个数组 dis[]:更新源点到各个点的距离 vis[]:标记是否访问 3.从源点开始,更新源点到与其邻接的点的距离,每次选…

鸿蒙OpenHarmony开发板解析:【特性配置规则】

特性 特性配置规则 下面介绍feature的声明、定义以及使用方法。 feature的声明 开发前请熟悉鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 在部件的bundle.json文件中通过feature_list来声明部件的feature列…

MQTT 5.0 报文解析 03:SUBSCRIBE 与 UNSUBSCRIBE

欢迎阅读 MQTT 5.0 报文系列 的第三篇文章。在上一篇中,我们介绍了 MQTT 5.0 的 PUBLISH 及其响应报文。现在,我们将介绍用于订阅和取消订阅的控制报文。 在 MQTT 中,SUBSCRIBE 报文用于发起订阅请求,SUBACK 报文用于返回订阅结果…

Java通过百度地图API获取定位-普通IP定位

项目中有一个登录邮箱提醒的功能,需要根据IP地址获取定位信息,从而更好地提示用户账号登录的所在地。为此,花费了一些时间来实现这个功能。 在CSDN搜索了一下,发现关于获取定位的文章说明都不够详细,于是决定自己创作一…

为什么要学Python?学Python有什么用?

为什么要学Python?学Python有什么用? 在当今的数字化时代,编程已成为一项宝贵的技能。Python,作为一种流行的编程语言,因其易于学习和强大的功能而受到全球开发者的青睐。本文将探讨学习Python的原因和它的实际应用&am…

【操作系统期末速成】​操作系统概述(定义|功能|特征)|发展阶段和分类|结构设计|概念补充

🎥 个人主页:深鱼~🔥收录专栏:操作系统🌄欢迎 👍点赞✍评论⭐收藏 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到…

Nginx部署前后端分离项目

部署前后端分离项目,要求前端项目、后端项目、数据库分别部署在3台服务器 服务器准备 服务器名IP软件包前端192.168.99.137nginx后端192.168.99.139jar数据库192.168.99.100mariadb 1、前端服务器 yum install -y epel-release && yum install -y nginx…

官宣:vAsterNOS正式发布!开放网络操作系统免费试用!

近期,vAsterNOS(设备模拟器)正式发布,可以满足用户快速了解 AsterNOS、体验实际操作、搭建模拟网络的需求,可运行在GNS3、EVE-NG等网络虚拟软件中。 AsterNOS 网络操作系统是星融元为人工智能、机器学习、高性能计算、…

vCenter 7.3证书过期无法登录处理方法

登录报错:如下图 Exception in invking authentication handler [SSL: CERTIFICATE_VERIFY_FAILED] certificate vertify failed: certificate has expired(_ssl.c:1076) 处理方法1:推荐,可行 登录vCenter控制台,AltF3切换至命令…

antdVue 自定义table列配置

最近做项目的时候需要对页面的table进行列配置的需求 子组件 <div><a-modaltitle"列配置" :visible"visible" :closable"false" :footer"null"width"800px" height"448px"><div><a-row>…

在linux里登录远程服务器

在linux里登录远程服务器。在虚拟终端里输入命令&#xff1a; ssh 远程服务器ip -l username 然后输入登录密码&#xff0c;就可以登录到远程服务器的命令行界面。登录方便&#xff0c;字体也可以在本地机的虚拟终端里设置得大一点。 下面是一张截屏图片。