tcp链接中的三次挥手是什么原因
一、tcp链接中的正常四次挥手过程?
刚开始双方都处于 ESTABLISHED 状态,假如是客户端先发起关闭请求。四次挥手的过程如下:
1、客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。2、接着,当服务端在 read 数据的时候,最后⾃然就会读到 EOF,接着 read() 就会返回 0,这时服务端应⽤程序如果有数据要发送的话,就发完数据后才调⽤关闭连接的函数,如果服务端应⽤程序没有数据要发送的话,可以直接调⽤关闭连接的函数,这时服务端就会发⼀个 FIN 包,这个 FIN 报⽂代表服务端不会再发送数据了,之后处于 LAST_ACK 状态;。
3、客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
4、等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。
5、客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态
6、服务端收到了 ACK 应答报文后,就进入了 CLOSE 状态,至此服务端已经完成连接的关闭。
7、客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态,至此客户端也完成连接的关闭。
你可以看到,每个方向都需要一个 FIN 和一个 ACK,因此通常被称为四次挥手。
这里一点需要注意是:主动关闭连接的,才有 TIME_WAIT 状态。
二、为什么挥手需要四次
服务器收到客户端的 FIN 报⽂时,内核会⻢上回⼀个 ACK 应答报⽂,但是服务端应⽤程序可能还有数据要发送,所以并不能⻢上发送 FIN 报⽂,⽽是将发送 FIN 报⽂的控制权交给服务端应⽤程序:
1、关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
2、服务端收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。
从上⾯过程可知,是否要发送第三次挥⼿的控制权不在内核,⽽是在被动关闭⽅(上图的服务端)的应⽤程序,因为应⽤程序可能还有数据要发送,由应⽤程序决定什么时候调⽤关闭连接的函数,当调⽤了关闭连接的函数,内核就会发送 FIN 报⽂了,所以服务端的 ACK 和 FIN ⼀般都会分开发送。
FIN 报⽂⼀定得调⽤关闭连接的函数,才会发送吗?不一定
如果进程退出了,不管是不是正常退出,还是异常退出(如进程崩溃),内核都会发送 FIN 报⽂,与对⽅完成四次挥⼿。
三、粗暴关闭 vs 优雅关闭
前⾯介绍 TCP 四次挥⼿的时候,并没有详细介绍关闭连接的函数,其实关闭的连接的函数有两种函数:
- close 函数,同时 socket 关闭发送⽅向和读取⽅向,也就是 socket 不再有发送和接收数据的能⼒。如果有多进程/多线程共享同⼀个 socket,如果有⼀个进程调⽤了 close 关闭只是让 socket 引⽤计数-1,并不会导致 socket 不可⽤,同时也不会发出 FIN 报⽂,其他进程还是可以正常读写该 socket, 直到引⽤计数变为 0,才会发出 FIN 报⽂。
- shutdown 函数,可以指定 socket 只关闭发送⽅向⽽不关闭读取⽅向,也就是 socket 不再有发送数据的能⼒,但是还是具有接收数据的能⼒。如果有多进程/多线程共享同⼀个 socket,shutdown 则不 管引⽤计数,直接使得该socket 不可⽤,然后发出 FIN 报⽂,如果有别的进程企图使⽤该 socket, 将会受到影响。
如果客户端是⽤ close 函数来关闭连接,那么在 TCP 四次挥⼿过程中,如果收到了服务端发送的数据,由于客户端已经不再具有发送和接收数据的能⼒,所以客户端的内核会回 RST 报⽂给服务端,然后内核会释放连接,这时就不会经历完成的 TCP 四次挥⼿,所以我们常说,调⽤ close 是粗暴的关闭。
当服务端收到 RST 后,内核就会释放连接,当服务端应⽤程序再次发起读操作或者写操作时,就能感知到连接已经被释放了:
- 如果是读操作,则会返回 RST 的报错,也就是我们常⻅的Connection reset by peer。
- 如果是写操作,那么程序会产⽣ SIGPIPE 信号,应⽤层代码可以捕获并处理信号,如果不处理,则默 认情况下进程会终⽌,异常退出。
相对的,shutdown 函数因为可以指定只关闭发送⽅向⽽不关闭读取⽅向,所以即使在 TCP 四次挥⼿过程中,如果收到了服务端发送的数据,客户端也是可以正常读取到该数据的,然后就会经历完整的 TCP 四次挥⼿,所以我们常说,调⽤ shutdown 是优雅的关闭。
但是注意,shutdown 函数也可以指定「只关闭读取⽅向,⽽不关闭发送⽅向」,但是这时候内核是不会发送 FIN 报⽂的,因为发送 FIN 报⽂是意味着我⽅将不再发送任何数据,⽽ shutdown 如果指定「不关闭发送⽅向」,就意味着 socket 还有发送数据的能⼒,所以内核就不会发送 FIN。
四、什么情况会出现三次挥⼿?
当被动关闭⽅(上图的服务端)在 TCP 挥⼿过程中,「没有数据要发送」并且「开启了 TCP 延迟确认机制」,那么第⼆和第三次挥⼿就会合并传输,这样就出现了三次挥⼿。
然后因为 TCP 延迟确认机制是默认开启的,所以导致我们抓包时,看⻅三次挥⼿的次数⽐四次挥⼿还多。
什么是 TCP 延迟确认机制?
当发送没有携带数据的 ACK,它的⽹络效率也是很低的,因为它也有 40 个字节的 IP 头 和 TCP 头,但却没有携带数据报⽂。为了解决 ACK 传输效率低问题,所以就衍⽣出了 TCP 延迟确认。
TCP 延迟确认的策略:
- 当有响应数据要发送时,ACK 会随着响应数据⼀起⽴刻发送给对⽅
- 当没有响应数据要发送时,ACK 将会延迟⼀段时间,以等待是否有响应数据可以⼀起发送
- 如果在延迟等待发送 ACK 期间,对⽅的第⼆个数据报⽂⼜到达了,这时就会⽴刻发送 ACK
相关文章:

tcp链接中的三次挥手是什么原因
一、tcp链接中的正常四次挥手过程? 刚开始双方都处于 ESTABLISHED 状态,假如是客户端先发起关闭请求。四次挥手的过程如下: 1、客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文…...
运维相关知识
一、运维需要关注 服务器的哪些数据? 1. CPU 1.1 CPU使用率: top,vmstat (1) 用户CPU使用率:用户态程序的使用率。top 命令 us 字段和 nice字段 (低优先级) (2) 系统CPU使用率:内核态程序的使用率。top 命令 sy 字…...

网络安全基础技术扫盲篇名词解释之“证书“
用通俗易懂的话说: 证书就好比是一张身份证(类似,但不完全相同),用来证明一个网站的身份是否可信。就像你要确认一个陌生人的身份需要看他的身份证一样,电脑在连接一个网站时,也会查看网站的证…...

[数据集][目标检测]老鼠检测数据集VOC+YOLO格式4107张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):4107 标注数量(xml文件个数):4107 标注数量(txt文件个数):4107 标注…...

12 FreeRTOS 调试与优化
1、调试 1.1 打印 在FreeRTOS工程中使用了microlib,里面实现了printf函数。 只需要实现一下以下函数即可使用printf。 int fputc(int ch; FILE *f); 假如要从串口实现打印函数: int fputc( int ch, FILE *f ) {//指定串口USART_TypeDef* USARTx USAR…...

【Qt秘籍】[009]-自定义槽函数/信号
自定义槽函数 在Qt中自定义槽函数是一个直接的过程,槽函数本质上是类的一个成员函数,它可以响应信号。所谓的自定义槽函数,实际上操作过程和定义普通的成员函数相似。以下是如何在Qt中定义一个自定义槽函数的步骤: 步骤 1: 定义槽…...

HTTPS加密
一.加密是什么 加密就是把明文(要传输的信息)进行一系列的变换,生成密文. 有加密就有解密,解密就是把密文进行一系列的变换,生成明文. 在这个加密和解密过程中,往往需要一个或多个中间数据,辅助进行这个过程,这样的数据称为密钥. 加密解密到如今已经发展成了一个独立的学科 : 密…...

搭建大型分布式服务(三十八)SpringBoot 整合多个kafka数据源-支持protobuf
系列文章目录 文章目录 系列文章目录前言一、本文要点二、开发环境三、原项目四、修改项目五、测试一下五、小结 前言 本插件稳定运行上百个kafka项目,每天处理上亿级的数据的精简小插件,快速上手。 <dependency><groupId>io.github.vipjo…...
SpringBoot如何使用日志Logback,及日志等级详解
Spring Boot默认已经集成了SLF4J(Simple Logging Facade for Java)作为日志的接口,以及Logback作为日志的实现。这意味着在大多数情况下,你无需做额外的配置即可开始记录日志。 下面是一个简要的指南,包括如何在Spring…...

若依启动run-modules-system.bat报错问题解决方案
在启动run-modules-system.bat时遇到了一些问题,在网上搜索无果后,排查解决完毕 1.启动nacos时,报错如下 Error creating bean with name grpcClusterServer: Invocation of init method failed; nested exception is java.io.IOException: Failed to bind to address 0.0.0.0…...

Aws CodeCommit代码仓储库
1 创建IAM用户 IAM创建admin用户,增加AWSCodeCommitFullAccess权限 2 创建存储库 CodePipeline -> CodeCommit -> 存储库 创建存储库 3 SSH 1) window环境 3.1.1 上载SSH公有秘钥 生成SSH秘钥ID 3.1.2 编辑本地 ~/.ssh 目录中名为“config”的 SSH 配置文…...
PostgreSQL的内存参数
PostgreSQL的内存参数 基础信息 OS版本:Red Hat Enterprise Linux Server release 7.9 (Maipo) DB版本:16.2 pg软件目录:/home/pg16/soft pg数据目录:/home/pg16/data 端口:5777PostgreSQL 提供了多种内存参数&#x…...
【教程】在CentOS上使用Docker部署前后端分离项目的完整指南
当在CentOS上使用Docker部署前后端分离项目时,需要遵循一系列步骤来实现这一目标。以下是每个步骤的详细内容: 步骤1:安装Docker和Docker Compose 1.1 安装Docker 在CentOS上安装Docker,可以按照以下步骤进行: sudo yum install -y yum-utils device-mapper-persistent…...

某公司新招了个牛逼的架构师后.....
网友评论: 架构师一个响指之后。第二天,老板不见了走走停停 回头已是数月图片是我的故事没错了,本来我们组有10个人,我把代码重构之后,只要半个人维护,于是老板要裁掉9个>人,于是我被搞走了图…...
云计算和雾计算
雾计算作为传统集中式数据存储系统(云)和边缘设备之间的中间层。雾扩展了云,使计算和数据存储更接近边缘。雾由多个节点(雾节点)组成,并创建一个本地网络,使其成为一个去中心化的生态系统——雾…...
正缘画像 api数据接口
测测正缘画像,相貌特征,高矮胖瘦,黑白美丑,对方何许人也,远嫁近娶,何方定居,家庭观,持家爱家,生活质量,富裕贫穷,健康情况,测算结果仅…...
Java 基础面试300题 (171- 200)
Java 基础面试300题 (171- 200) 171.什么是同步? 当多个线程试图同时访问共享资源时,那么他们需要以某种方式让资源一次只能由一个线程访问。实现这一目标的过程被称为同步。Java提供了一个名为synchronized的关键字实现这一目标…...

0基础学习Elasticsearch-使用Java操作ES
文章目录 1 背景2 前言3 Java如何操作ES3.1 引入依赖3.2 依赖介绍3.3 隐藏依赖3.4 初始化客户端(获取ES连接)3.5 发送请求给ES 1 背景 上篇学习了0基础学习Elasticsearch-Quick start,随后本篇研究如何使用Java操作ES 2 前言 建议通篇阅读再回…...
【Linux】GNU编译器基础
文章目录 GCCMakefile、make GCC 常见的GNU编译器是GCC其包含gcc以及g等,适用于C/C中,在Windows系统中通常使用IDE进行程序的编写和编译、链接等操作,但在Linux系统中通常使用GNU编译器来进行,对于C/C等高级语言需要进行预编译、编…...
Linux 软件安装:从源码编译到包管理器安装
Linux 软件安装:从源码编译到包管理器安装 在 Linux 操作系统中,软件安装是一个非常重要的任务。不同的软件安装方式有不同的优缺点,本篇博客将介绍 Linux 软件安装的几种方式,包括从源码编译安装、使用包管理器安装和使用第三方…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...