图解 TCP 四次挥手|深度解析|为什么是四次|为什么要等2MSL
写在前面
今天我们来图解一下TCP的四次挥手、深度解析为什么是四次?
上一片文章我们已经介绍了TCP的三次握手

解析四次挥手
数据传输完毕之后,通信的双方都可释放连接。现在客户端A和服务端B都处于ESTABLISHED状态。

第一次挥手
客户端A的应用进程先向TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接。客户端A把链接释放报文段首部的终止控制位FIN置为1,其序号为seq=u,它等于前面以传送过的数据的最后一个字节的序号加1。这时候A进入了FIN-WAIT-1(终止等待1)状态,等待B的确认。
注意:TCP规定:FIN报文段即使不携带数据,也消耗掉一个序号!!

第二次挥手
服务端B收到链接释放报文段后即发出确认,确认号是ack = u + 1,而这个报文段自己的序号v是等于B前面已传送过的数据的最后一个字节的序号加1,然后B就进入CLOSE-WAIT(关闭等待)状态。

TCP服务器进程这时应通知应用进程,因而从A到B这个方向的链接就释放了。这时的TCP链接处于半关闭状态,即A已经没有数据要发送了,但B若发送数据,A仍要接收,也就是说,从B到A这个方向的连接并未关闭,这个状态要维持一段时间。
第三次挥手
A收到来自B的确认后,就进入了FIN-WAIT-2(终止等待2)状态满等待B发出的连接释放报文段。若B已经没有要向A发送的数据,其应用进程就通知TCP释放连接,这时B发出的连接释放报文段必须使FIN = 1,现假定B的序号为w,B还必须重复上次已发送过的确认号ack = u + 1.这时B就进入LAST-ACK(最后确认)状态,等待A的确认。

第四次挥手
A在收到了B的链接释放报文段后,必须对此发出确认。在确认报文段中把ACK置1,确认号ack=w+1,而自己的序号是seq=u+1(根据TCP标准,前面发送过的FIN报文段要消耗一个序号),然后进入到TIME-WAIT(时间等待)状态。
注意: 现在TCP连接还没有还没有释放掉。必须经过时间等待计时器设置的时间2MSL后,A才能进入CLOSED状态。
MSL叫做最长报文段寿命,RFC793建议设在两分钟,但TCP允许不同的实现可以根据具体情况使用更小的MSL值。

为什么要2MSL时间呢
1. 为了保证A发送的最后一个ACK报文段能够到达B。
这个ACK报文段有可能丢失,因而使处于在LAST-ASK状态的B收不到对己发送的FIN-ACK报文段的确认。B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的FIN+ACK报文段。接着A重传一次确认,重新启动2MSL计时器,最后的A和B都正常进入CLOSED状态。

如果A在TIME-WAIT状态不等待一段时间,而是发送完ACK报文段后立即释放连接,那么就无法收到B重传的FIN+ACK报文段,因而也不会再发送一次确认报文段。
2. 防止了已失效的连接请求报文段。
A 在发送完最后一个ACK报文段后,在经过时间2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,这样就可以使下一个连接中不会出现这种旧的连接请求报文段。B只要收到了A发出的确认,就进入CLOSED状态。同样,B在撤销相应的传输控制块TCB后,就结束了这次的TCP连接,所以B结束TCP连接的时间要比A早一些的。
为什么是四次?
首先我们可以确定一点TCP是全双工的,四次挥手是保证了双方都知道并且都已经断开连接。

四次挥手过程的目的是确保数据在关闭过程中能够被完整传输,同时也允许延迟的数据包在关闭后仍然能够被接收。TIME_WAIT 状态的存在是为了处理可能的重复数据包,以确保连接的完全关闭。
⚠️ 注意一点:关闭连接时,客户端A向服务端B发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
问题又来了:为什么握手要三次,挥手却要四次呢?
服务器B收到客户端A的 FIN 报文时,先回一个 ACK 应答报文,而B可能还有数据需要处理和发送,等B不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。
握手的时候并没有数据传输,所以服务端的 SYN 和 ACK 报文可以一起发送,但是挥手的时候有数据在传输,服务端B通常需要等待完成数据的发送和处理, 所以服务端B的 ACK 和 FIN 一般都会分开发送,从而比三次握手导致多了一次。
参考
[1] https://segmentfault.com/a/1190000040571193
相关文章:
图解 TCP 四次挥手|深度解析|为什么是四次|为什么要等2MSL
写在前面 今天我们来图解一下TCP的四次挥手、深度解析为什么是四次? 上一片文章我们已经介绍了TCP的三次握手 解析四次挥手 数据传输完毕之后,通信的双方都可释放连接。现在客户端A和服务端B都处于ESTABLISHED状态。 第一次挥手 客户端A的应用进…...
DevExpress中文教程:如何将WinForms数据网格连接到ASP. NET Core WebAPI服务?
日前DevExpress官方发布了DevExpress WinForms的后续版本——将.NET桌面客户端连接到安全后端Web API服务(EF Core with OData),在本文中我们将进一步演示如何使用一个更简单的服务来设置DevExpress WinForms数据网格。 P.S:DevExpress WinForms拥有180…...
SpringBoot3核心特性-核心原理
目录 传送门前言一、事件和监听器1、生命周期监听2、事件触发时机 二、自动配置原理1、入门理解1.1、自动配置流程1.2、SPI机制1.3、功能开关 2、进阶理解2.1、 SpringBootApplication2.2、 完整启动加载流程 三、自定义starter1、业务代码2、基本抽取3、使用EnableXxx机制4、完…...
Linux:RPM软件包管理以及yum软件包仓库
挂载光驱设备 RPM软件包管理 RPM软件包简介 区分软件名和软件包名 软件名:firefox 软件包名:firefox-52.7.0-1.el7.centos.x86_64.rpm 查询软件信息 查询软件(参数为软件名) ]# rpm -qa #当前系统中所有已安装的软件包 ]# r…...
pod介绍与配置
1、pod概念介绍 Pod 是 kubernetes 基本调度单位。每个 Pod 中可以运 行一个或多个容器,共享 Pod 的文件系统、IP 和网络等资源,每个 Pod 只有一个 IP。 2、使用 yaml或json 文件创建 Pod 声明式文件方式创建 Pod,支持 yaml 和 json 1&…...
【Taro】初识 Taro
笔记来源:编程导航。 概述 Taro 官方文档:https://taro-docs.jd.com/docs/ (跨端开发框架) Taro 官方框架兼容的组件库: taro-ui:https://taro-ui.jd.com/#/ (最推荐,兼容性最好&…...
【设计模式-备忘录】
备忘录模式(Memento Pattern)是一种行为型设计模式,用于保存对象的内部状态,以便在将来某个时间可以恢复到该状态,而不暴露对象的内部实现细节。备忘录模式特别适合在需要支持撤销(Undo)操作的应…...
【数据结构】排序算法系列——快速排序(附源码+图解)
快速排序 接下来我们将要介绍的是排序中最为重要的算法之一——快速排序。 快速排序(英语:Quicksort),又称分区交换排序(partition-exchange sort),最早由东尼霍尔提出。快速排序通常明显比其…...
Arthas thread(查看当前JVM的线程堆栈信息)
文章目录 二、命令列表2.1 jvm相关命令2.1.2 thread(查看当前JVM的线程堆栈信息)举例1:展示[数字]线程的运行堆栈,命令:thread 线程ID举例2:找出当前阻塞其他线程的线程 二、命令列表 2.1 jvm相关命令 2.…...
Tomcat_WebApp
Tomcat的目录的介绍 /bin: 这个目录包含启动和关闭 Tomcat 的脚本。 startup.bat / startup.sh:用于启动 Tomcat(.bat 文件是 Windows 系统用的,.sh 文件是 Linux/Unix 系统用的)。shutdown.bat / shutdown.sh…...
代码随想录算法训练营Day10
150. 逆波兰表达式求值 力扣题目链接;. - 力扣(LeetCode) Collection——Deque——LInkedList类 class Solution {public int evalRPN(String[] tokens) {Deque<Integer> myquenew LinkedList<>();for(String a:tokens){if(a.…...
十个服务器中毒的常见特征及其检测方法
服务器作为企业的核心资源,其安全性至关重要。一旦服务器被病毒入侵,不仅会影响系统的正常运行,还可能导致数据泄露等严重后果。以下是十种常见的服务器中毒特征及其检测方法。 1. 系统性能下降 病毒常常占用大量的CPU和内存资源࿰…...
LeetCode 每周算法 6(图论、回溯)
LeetCode 每周算法 6(图论、回溯) 图论算法: class Solution: def dfs(self, grid: List[List[str]], r: int, c: int) -> None: """ 深度优先搜索函数,用于遍历并标记与当前位置(r, c)相连的所有陆地&…...
Selenium元素定位:深入探索与实践
目录 一、引言 二、Selenium元素定位基础 1. WebDriver与元素定位 2. 定位策略概览 三、ID定位 1. 特点与优势 2. 示例代码 四、Class Name定位 1. 特点与限制 2. 示例代码 五、XPath定位 1. 特点与优势 2. 示例代码 3. XPath高级用法 六、CSS Selector定位 1.…...
前端开发——(1)使用vercel进行网页开发
前端开发——(1)使用Vercel进行网页开发 在现代前端开发中,选择一个高效的部署平台至关重要。Vercel 提供了快速、简便的部署方式,特别适合静态网站和 Next.js 应用。本文将带你逐步了解如何使用 Vercel 部署并运行你的网页项目。…...
故障诊断│GWO-DBN灰狼算法优化深度置信网络故障诊断
1.引言 随着人工智能技术的快速发展,深度学习已经成为解决复杂问题的热门方法之一。深度置信网络(DBN)作为深度学习中应用比较广泛的一种算法,被广泛应用于分类和回归预测等问题中。然而,DBN的训练过程通常需要大量的…...
【工具】Windows|两款开源桌面窗口管理小工具Deskpins和WindowTop
总结 Deskpins 功能单一,拖到窗口上窗口就可以置顶并且标记钉子标签,大小 104 KB,开源位置:https://github.com/thewhitegrizzli/DeskPins/releases WindowTop 功能完善全面强大,包括透明度、置顶、选区置顶等一系列功…...
【Unity杂谈】iOS 18中文字体显示问题的调查
一、问题现象 最近苹果iOS 18系统正式版推送,周围升级系统的同事越来越多,有些同事发现,iOS 18上很多游戏(尤其是海外游戏)的中文版,显示的字很奇怪,就像一些字被“吞掉了”,无法显示…...
后端-navicat查找语句(单表与多表)
表格字段设置如图 语句: 1.输出 1.输出name和age列 SELECT name,age from student 1.2.全部输出 select * from student 2.where子语句 1.运算符: 等于 >大于 >大于等于 <小于 <小于等于 ! <>不等于 select * from stude…...
基于springboot的在线视频点播系统
文未可获取一份本项目的java源码和数据库参考。 国外研究现状: 与传统媒体不同的是,新媒体在理念和应用上都采用了新颖的媒介或媒体。新媒体是指应用在数字技术、在传统媒体基础上改造、或者更新换代而来的媒介或媒体。新兴媒体与传统媒体在理念和应用…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
Qt的学习(一)
1.什么是Qt Qt特指用来进行桌面应用开发(电脑上写的程序)涉及到的一套技术Qt无法开发网页前端,也不能开发移动应用。 客户端开发的重要任务:编写和用户交互的界面。一般来说和用户交互的界面,有两种典型风格&…...
