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.rhkb.cn/news/324109.html

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

相关文章

cocos中的meta文件有什么用?如何生成?

cocos中的.meta文件有什么用?如何生成? 1. .meta文件有什么用? Cocos Creator 会为 assets 目录下的每一个文件和目录生成一个同名的 meta 文件 示例 {"ver": "4.0.23", // 版本"importer": "typescr…

基于ESP32和ESP8266的物联网开发过程(二)

在做这个项目前,也做了一些调研。项目的初衷是想要用于智能家居。我比较了小米IoT、阿里云、ESPHOME、巴沙云、点灯科技和ONENET等几个平台。最终选择了Onenet,部分原因是之前用过它的多协议版本,但现在这个版本已经下线了。 小米IoT的公测名…

Linux - make与makefile

文章目录 什么是make和makefile如何使用依赖关系 和 依赖方法伪目标 写个程序-进度条换行和回车的区别 什么是make和makefile make是一个命令 makefile是一个文件 这就是make和makefile的本质 make和 ll , pwd ,su 一样都是命令 makefile和 test , test.c 一样都是…

GPT+Python近红外光谱数据分析

原文链接:GPTPython近红外光谱数据分析https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247603913&idx1&sn6eb8fd6f1abcdd8160815997a13eb03d&chksmfa82172ecdf59e389a860547a238bb86c7f38ae3baa14e97c7490a52ef2a2c206f88d503a5eb&token…

【WPF学习笔记(一)】WPF应用程序的组成及Window类介绍

WPF应用程序的组成及Window类介绍 WPF应用程序的组成及Window类介绍前言正文1、WPF介绍1.1 什么是WPF1.2 WPF的特点1.3 WPF的控件分类 2、XAML介绍2.1 XAML的定义2.2 XAML的特点2.3 XAML的命名空间 3、WPF应用程序组成3.1 App.config3.2 App.xaml3.3 App.xaml.cs3.4 MainWindow…

分布式存储CephFS最佳实践

文章来源于知乎文章: 分布式存储CephFS最佳实践 背景 近日,一朋友说他们企业内部想落地CephFS,让我帮忙写一份能落地的CephFS最佳实践。然后就顺便把文章整理到了这里。因能力水平以及认知有限,如有错漏烦请指正。 简介 CephF…

IP 地理定位神话与事实

ip地理定位是一项技术,用于通过访问设备的ip地址来获取地理位置信息,例如国家、城市、经纬度等。该技术广泛应用于网站内容自定义、广告定位、网络安全和用户分析等领域。它通过与包含ip地址和地理位置映射的大型数据库进行查询来工作,但在准…

聊聊测试团队管理

管理测试团队是一个复杂但至关重要的任务,它不仅关乎于保证软件产品的质量,还涉及到团队建设、流程优化、技能提升等多个方面。以下是一些关键策略,可以帮助您有效地管理测试团队,比如“持续培训和技术支持,明确目标&a…

99、技巧-下一个排列

这个问题要求生成一个数组的下一个排列。所谓“下一个排列”指的是,在所有数字相同但顺序不同的排列中,找出数字序列中刚好比当前序列大的下一个序列。如果当前序列已经是这些排列中的最大值,则下一个排列应该是最小的排列。 思路解释 要解…

QML 本地存储(Setting,sqlite)

Qt hello - 专注于Qt的技术分享平台 QML 原生的储存方有两种: 1,Settings 跟QWidget 中的QSettings 一样,可以简单的存储一些配置。 2,Sqlite sqlite数据库。可以存储一些复杂的数据。 一,Settings 我们以一个按钮的位…

【机器学习300问】81、什么是动量梯度下降算法?

动量梯度下降算法(Momentum)是利用指数加权移动平均的思想来实现梯度下降的算法。让我们先来回顾一下基础的梯度下降方法以及看看它有哪些不足之处。接着引出动量梯度下降算法,在理解了它的原理后看看它是如何规避之前方法的不足的。 如果不知…

Spring如何控制Bean的加载顺序

前言 正常情况下,Spring 容器加载 Bean 的顺序是不确定的,那么我们如果需要按顺序加载 Bean 时应如何操作?本文将详细讲述我们如何才能控制 Bean 的加载顺序。 场景 我创建了 4 个 Class 文件,分别命名为 FirstInitialization Se…

如何使用 ERNIE 千帆大模型基于 Flask 搭建智能英语能力评测对话网页机器人(详细教程)

ERNIE 千帆大模型 ERNIE-3.5是一款基于深度学习技术构建的高效语言模型,其强大的综合能力使其在中文应用方面表现出色。相较于其他模型,如微软的ChatGPT,ERNIE-3.5不仅综合能力更强,而且在训练与推理效率上也更高。这使得ERNIE-3…

第三节课,功能2:开发后端用户的管理接口-- postman--debug测试

一、如何使用postman 网址: https://www.postman.com/downloads/ 【Postman小白教程】五分钟学会如何使用Postman~_哔哩哔哩_bilibili postman安装使用_bowser agent在postman哪里-CSDN博客 二、下载后 登录,开始测试 2.1 关于postman 报错&#…

第十五届蓝桥杯python B组省赛

前言: 这是我第一次参加蓝桥杯,成绩并不理想,我反思了一下午,我的问题主要是知识点学不透,题目做的太少,而且学习的时候少数时间不专心,但是,我能感觉到我的学习能力并不弱&#xf…

分布式锁讲解

概括 分布式锁是一种用于在分布式系统中实现同步机制的锁。在单机系统中,我们可以使用如Java中的synchronized关键字或者 ReentrantLock来实现线程间的同步,但在分布式系统中,由于多个节点(服务器)之间的并发操作&am…

C语言实现扫雷游戏完整版

游戏介绍: 目录 游戏介绍: 游戏框架: 游戏具体功能实现: 棋盘的定义: 棋盘初始化: 棋盘打印: 棋盘布置雷: 棋盘扫雷: 爆炸展开一片: 获取周围八个…

WP Rocket插件下载:加速您的WordPress网站,提升用户体验

在互联网速度决定用户体验的今天,一个快速加载的网站对于吸引和保留访问者至关重要。WP Rocket插件,作为一款专为WordPress设计的高性能缓存插件,提供了一套完整的解决方案,帮助您优化网站性能,提升用户体验。 [WP Ro…

Linux随记(九)

一、在bclinux Euler 21.10 安装oracle19c客户端 (为了使用sqlplus 、expdp、impdp、sqlldr等指令) #环境和说明 系统:BigCloud Enterprise Linux For Euler 21.10 LTS 为了使用sqlplus 、expdp、impdp、sqlldr等指令。 下面是安装步骤 &…

力扣打卡第二天

206. 反转链表 class Solution { public:ListNode* reverseList(ListNode* head) {// //迭代法// ListNode *pre nullptr;// ListNode *curr head;// while(curr){// ListNode *next curr -> next;// curr -> next pre;// pre curr;// curr next;/…