详述 TCP 的 TIME_WAIT 状态要维持 2MSL 的原因

2023-05-16

文章目录

  • 前言
  • 正文

前言

本文主要分析为什么 TIME_WAIT 状态的持续时间是 2MSL 而不是 1MSL,3MSL 或其它的时长,而不会详细描述为什么需要 TIME_WAIT 状态。阅读本文需要的预备知识:

  • 了解 TCP 协议的状态变迁;
  • 了解 TCP 拆链的四次挥手过程;
  • 了解为什么需要 TIME_WAIT 状态。

正文

其实这个问题在《TCP/IP详解》以及《UNIX网络编程》这两本书中都有提及,但这两本书上的描述都比较简洁并不是特别容易理解,记得在第一次看《UNIX网络编程》时,我曾经反复阅读相关段落并花了不少时间来想这个问题,但并没有搞得很清楚,始终是懂非懂的样子,直至后来有机会参与 TCP/IP 协议栈的开发后才真正 get 到这个问题的关键点。

根据第三版《UNIX网络编程 卷1》2.7 节,TIME_WAIT 状态的主要目的有两个:

  • 优雅的关闭 TCP 连接,也就是尽量保证被动关闭的一端收到它自己发出去的 FIN 报文的 ACK 确认报文
  • 处理延迟的重复报文,这主要是为了避免前后两个使用相同四元组的连接中的前一个连接的报文干扰后一个连接

很明显,要实现上述两个目标,TIME_WAIT 状态需要持续一段时间,但这段时间应该是多长呢?

如果只考虑上述第一个目标,则 TIME_WAIT 状态需要持续的时间应该参考对端的 RTO(重传超时时间)以及 MSL(报文在网络中的最大生存时间)来计算而不是仅仅按 MSL 来计算,因为只要对端没有收到针对 FIN 报文的 ACK,就会一直持续重传 FIN 报文直到重传超时,所以最能实现完美关闭连接的时长计算方式应该是从对端发送第一个 FIN 报文开始计时到它最后一次重传 FIN 报文这段时长加上 MSL,但这个计算方式过于保守,只有在所有的 ACK 报文都丢失的情况下才需要这么长的时间;另外,第一个目标虽然重要,但并不十分关键,因为既然已经到了关闭连接的最后一步,说明在这个 TCP 连接上的所有用户数据已经完成可靠传输,所以要不要完美的关闭这个连接其实已经不是那么关键了。因此,(我猜)RFC 标准的制定者才决定以网络丢包不太严重为前提条件,然后根据第二个目标来计算 TIME_WAIT 状态应该持续的时长。

再来看一下《UNIX网络编程》在描述为什么需要 TIME_WAIT 状态时的一段话:

Since the duration of the TIME_WAIT state is twice the MSL, this allows MSL seconds for packet in one direction to be lost, and another MSL seconds for the reply to be lost. By enforcing this rule, we are guaranteed that when we successfully establish a TCP connecton, all old duplicates from previous incarnations of the connection have expired in the network.

这段文字说明了 TIME_WAIT 状态持续 2MSL 的时间可以让一个 TCP 连接的两端发出的报文都从网络中消失,从而保证下一个使用了相同四元组的 TCP 连接不会被上一个连接的报文所干扰。

如何理解 TIME_WAIT 状态持续 2MSL 的时间就可以让一个 TCP连 接的两端发出的报文都从网络中消失呢?

首先我们需要了解如下要点:

  1. TCP 连接中的一端发送了 FIN 报文之后如果收不到对端针对该 FIN 的 ACK,则会反复多次重传 FIN 报文,大约持续几分钟;
  2. 被动关闭处于 LAST_ACK 状态的一端在收到最后一个 ACK 之后不会发送任何报文,立即进入 CLOSED 状态;
  3. 主动关闭的一端在收到被动关闭端发送过来的 FIN 报文并回复 ACK 之后进入 TIME_WAIT 状态;
  4. 之所以 TIME_WAIT 状态需要维持一段时间而不是进入 CLOSED 状态,是因为需要处理对端可能重传的 FIN 报文或其它一些因网络原因而延迟的数据报文,不处理这些报文可能导致前后两个使用相同四元组的连接中的后一个连接出现异常(详见《UNIX网络编程》卷 1 的 2.7 节 第三版);
  5. 处于 TIME_WAIT 状态的一端在收到重传的 FIN 时会重新计时(rfc793以及 Linux Kernel 源代码tcp_timewait_state_process函数)。

下面我们开始分析为什么在发送了最后一个 ACK 报文之后需要等待 2MSL 时长来确保没有任何属于当前连接的报文还存活于网络之中(前提是在这 2MSL 时间内不再收到对方的 FIN 报文,但即使收到了对端的 FIN 报文也并不影响我们的讨论,因为如果收到 FIN 则会回复 ACK 并重新计时)。

为了便于描述,我们设想有一个处于拆链过程中的 TCP 连接,这个连接的两端分别是 A 和 B,其中 A 是主动关闭连接的一端,因为刚刚向对端发送了针对对端发送过来的 FIN 报文的 ACK,此时正处于 TIME_WAIT 状态;而 B 是被动关闭的一端,此时正处于 LAST_ACK 状态,在收到最后一个 ACK 之前它会一直重传 FIN 报文直至超时。随着时间的流逝,A 发送给 B 的 ACK 报文将会有两种结局:

  1. ACK 报文在网络中丢失;如前所述,这种情况我们不需要考虑,因为除非多次重传失败,否则 AB 两端的状态不会发生变化直至某一个 ACK 不再丢失。
  2. ACK 报文被 B 接收到。我们假设 A 发送了 ACK 报文后过了一段时间t之后 B 才收到该 ACK,则有0 < t <= MSL。因为 A 并不知道它发送出去的 ACK 要多久对方才能收到,所以 A 至少要维持 MSL 时长的 TIME_WAIT 状态才能保证它的 ACK 从网络中消失。同时处于 LAST_ACK 状态的 B 因为收到了 ACK,所以它直接就进入了 CLOSED 状态,而不会向网络发送任何报文。所以晃眼一看,A 只需要等待 1 个 MSL 就够了,但仔细想一下其实 1 个 MSL 是不行的,因为在 B 收到 ACK 前的一刹那,B 可能因为没收到 ACK 而重传了一个 FIN 报文,这个 FIN 报文要从网络中消失最多还需要一个 MSL 时长,所以 A 还需要多等一个 MSL。

综上所述,TIME_WAIT 至少需要持续 2MSL 时长,这 2 个 MSL 中的第一个 MSL 是为了等自己发出去的最后一个 ACK 从网络中消失,而第二 MSL 是为了等在对端收到 ACK 之前的一刹那可能重传的 FIN 报文从网络中消失。另外,虽然说维持 TIME_WAIT 状态一段时间有 2 个目的,但这段时间具体应该多长主要是为了达成上述第二个目的而设计的。


  • 原文链接:https://www.cnblogs.com/abozhang/p/10974627.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

详述 TCP 的 TIME_WAIT 状态要维持 2MSL 的原因 的相关文章

  • Latex/CTex/WinEdt 将参考文献设为上标引用,并加方括号

    工作环境 xff1a pdfTeX 3 1415926 2 3 1 40 12 MiKTeX 2 9 WinEdt 7 在LateX中 xff0c 参考文献的引用一般有两种方式 xff0c 平 齐 时 用 命 令 cite 上 标 时用 t
  • IDEA中报错:Invalid VCS root mapping

    1 错误 当打开从别的渠道获得的项目代码 xff0c 用IDEA打开出现 Invalid VCS root mapping The directory 的错误 2 分析 原因 xff1a 目录所示的git项目不存在 xff0c 导致这个报错
  • 重试机制 Retry

    文章目录 1 重试1 1 重试作用 2 重试的三种方法2 1 java retry2 2 spring retry2 3 guava retrying2 3 1 重试源2 3 2 自定义重试监听器 RetryListener2 3 3 停止
  • win10系统开机输入密码黑屏解决方法

    第一步 xff1a 首先打开笔记本电脑开机 xff0c 输入开机密码进入第二步 xff1a 输入密码后显示黑屏 xff0c 按 Ctrl 43 Alt 43 Del 34 组合键打开任务管理器第三步 xff1a 在打开的任务管理器中 xff
  • Windows下LaTex转为Word

    文章目录 1 latex gt pdf gt word1 1 以word打开1 2 使用adobe acrobat DC打开 2 latex typora gt word xff08 pandoc xff09 2 0 参数介绍2 1 安装p
  • SQL:用count求group by分组的个数

    1 求每一分组内的个数 查询选修了全部课程的学生姓名 思路 查询一个学生的姓名 xff0c 该学生选修课的门数等于所有课程的门数 逆推 xff1a 查询一个学生的姓名 xff0c 姓名怎么来 xff1f 通过Student的学号得到 xff
  • SQL:数据去重的三种方法

    1 使用distinct去重 distinct用来查询不重复记录的条数 xff0c 用count distinct id 来返回不重复字段的条数 用法注意 xff1a distinct 查询字段 xff0c 必须放在要查询字段的开头 xff
  • Word页面中四个直角

    文章目录 1 四个直角1 xff09 代表页边距2 xff09 页边距的设置3 xff09 打开或关闭 裁剪标记 2 裁剪标记 与图片1 xff09 插入图片超过这个角能打印显示出来吗 xff1f 3 裁剪标记 与表格 1 四个直角 1 x
  • windows搭建ftp及原理(小白向)

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 环境一 实验步骤1 1安装ftp 二 ftp实验引发的思考1 简单阐述ftp的原理2 ftp建立的流程 总结 环境 windwo
  • Win10系统自动更新失败(错误代码0x800f0922)

    笔者最近遇到了Win10系统自动更新失败的问题 xff0c 错误代码0x800f0922 每次更新下载安装完 xff0c 重启电脑的时候就会提示 xff1a 我们无法完成更新 正在撤销更改 在设置 Windows更新中有 xff1a 202
  • Linux yum安装redis

    1 安装redis数据库 yum install redis 2 下载fedora的epel仓库 yum install epel release 3 启动redis服务 systemctl start redis 4 查看redis状态
  • Centos 开启X11 Forwarding,实现无桌面环境运行GUI软件

    文章目录 修改SSH配置文件sshd config安装 X11 Forwarding 相关软件重启 sshd 服务 xff0c 并重新SSH连接验证 我们新安装Centos时可能会选择最小安装 xff0c 不安装桌面环境 xff0c 但是后
  • Python pyttsx3|文本朗读(各种语言)

    Python文字转语音 程序员 xff0c 在其他人眼中往往都是高冷的存在 xff0c 在他们的眼中能用代码解决的问题绝对不考虑其他的方法 xff0c 本文让我们用Python来提升一下高冷的档次 xff0c 让我们用代码来 说话 安装py
  • Spring Security 出现 'login.html?error' is not a valid redirect URL 异常

    原因是这个URL地址要以 打头 例如 xff1a 报错的代码 xff1a http span class token punctuation span span class token function formLogin span spa
  • 5. Python3的基本类型(元组)

    Python3的基本类型 xff08 元组 xff09 1 Python 的元组与列表相似 xff0c 不同之处 xff1a 元组不能修改 xff0c 元组使用小括号 xff0c 列表使用方括号 2 元组的创建 xff1a 只需要在括号中添
  • group by内部排序

    规则 xff1a 第一 xff0c 凡是在group by后面出现的字段 xff0c 必须同时在select后面出现 xff1b 第二 xff0c 凡是在select后面出现的 同时未在聚合函数中出现的字段 xff0c 必须同时出现在gro
  • 李宏毅机器学习(四)Spatial Transformer Layer

    学习内容 架构 xff1b 目的就是克服CNN的旋转和缩放不变性的缺点的 xff01 前情提要 CNN is not invariant to scaling and rotation xff1b CNN对缩放和旋转不是不变的 xff1b
  • python修改pip安装镜像源

    pip 默认的安装源安装真的很慢 xff0c 所以我们可以换成国内的一些优质的安装源 通用临时方法 pip install package name i https pypi tuna tsinghua edu cn simple 永久修改
  • 深入理解 Java 线程池的实现原理

    文章目录 1 线程状态2 线程池2 1 线程池的作用2 2 线程池的实现2 2 1 线程池内部状态 1 线程状态 既然要说线程 xff0c 我们就先来了解一下线程的几种状态 xff1a span class token keyword pu
  • windows server安装域控及原理(小白向)

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 安装环境一 安装域控二 说明一下遗留的问题总结 这个是一系列的博客文章 xff0c 域控只是开始 安装环境 windwos任意s

随机推荐

  • 详述 Redis 选择单线程模型的原因以及 I/O 多路复用

    文章目录 Redis 选择单线程模型的原因概述设计单线程模型可维护性并发处理性能瓶颈 引入多线程删除操作 总结 Redis 和 IO 多路复用几种 I O 模型Blocking I OI O 多路复用 Reactor 设计模式I O 多路复
  • 新一代垃圾回收器 ZGC 的探索与实践

    文章目录 GC之痛CMS 与 G1 停顿时间瓶颈标记阶段停顿分析清理阶段停顿分析复制阶段停顿分析 ZGC原理全并发的 ZGCZGC 关键技术ZGC 并发处理演示 ZGC 调优实践调优基础知识理解 ZGC 重要配置参数理解 ZGC 触发时机理
  • 详述 Spring 中 Bean 的作用域、事务的隔离级别以及传播行为

    文章目录 Bean 作用域XML 声明singletonprototyperequestsessionglobalSession 注解声明 事务隔离级别事务传播行为 Bean 作用域 Spring IOC 容器创建一个 Bean 实例时 x
  • 饿了么交易系统 5 年演化史

    作者介绍 xff1a 杨凡 xff0c 花名挽晴 xff0c 饿了么高级架构师 xff0c 2014 年加入饿了么 xff0c 2018 年随饿了么被阿里巴巴收购一同加入阿里巴巴 xff0c 4 年团队管理经验 xff0c 4 年主要从事饿
  • 带你了解「美团、百度和滴滴」的分布式 ID 生成系统

    文章目录 美团背景常见方法介绍UUID类snowflake方案数据库生成 Leaf 方案实现Leaf segment 数据库方案双 buffer 优化Leaf 高可用容灾 Leaf snowflake 方案弱依赖 ZooKeeper解决时钟
  • Spring Cloud 优雅下线以及灰度发布

    文章目录 前言优雅下线常见的下线方式优雅的下线方式 灰度发布蓝绿部署滚动部署金丝雀部署 前言 在生产环境中 xff0c 如何保证在服务升级的时候 xff0c 不影响用户的体验 xff0c 这个是一个非常重要的问题 如果在我们升级服务的时候
  • 详述 IntelliJ IDEA 遇到 Maven 项目 pom.xml 文件没有识别的解决方法

    文章目录 问题现象解决方法 问题现象 有的时候 xff0c 我们可能会遇到 IDEA 没有识别 Maven 项目pom xml的问题 xff0c 其表现出来的现象就是 xff1a 究其原因 xff0c 就是 IDEA 把pom xml文件当
  • Spring Boot 自定义 Swagger2 请求 URL 路径的两种方法

    文章目录 前言方法一 xff1a 修改应用根路径方法二 xff1a 引入 Swagger2 前端代码总结 前言 首先 xff0c 把 Swagger2 的依赖引进来 xff1a span class token comment lt swa
  • 使用 Apollo 为静态变量赋值的方法

    Apollo xff08 阿波罗 xff09 是携程框架部门研发的分布式配置中心 xff0c 能够集中化管理应用不同环境 不同集群的配置 xff0c 配置修改后能够实时推送到应用端 xff0c 并且具备规范的权限 流程治理等特性 xff0c
  • 记一次 Gorm 批量插入遇到的问题以及解决方案

    文章目录 问题现象解决方案 问题现象 最初 xff0c 我们用的是老版本的 Gorm xff0c 但是因为老版本不支持批量插入的功能 xff0c 所以我们将 Gorm 做了升级 xff0c 升级到1 21 9版本 https github
  • 3-Raven2百个靶机渗透(精写-思路为主)

    特别注明 xff1a 本文章只用于学习交流 xff0c 不可用来从事违法犯罪活动 xff0c 如使用者用来从事违法犯罪行为 xff0c 一切与作者无关 文章目录 前言一 信息收集二 ssh爆破尝试三 根据框架exp和cve拿shell四 对
  • 在 MacOS 系统的 /home 目录下创建文件夹的方法

    文章目录 前言修改 auto master加载 auto master创建自定义文件夹 前言 Rt xff0c 本文讲述如何在 Mac OS 系统中 xff0c 在 home目录下创建文件夹的方法 之所以会有本篇文章 xff0c 是因为在默
  • 在 MacOS 系统下创建 /home 目录的方法

    文章目录 前言SIP关闭SIP打开SIP查看 SIP 当前状态 创建 home 目录 前言 在 在 MacOS 系统的 home 目录下创建文件夹的方法 这篇文章中 xff0c 我们描述了如何在 home目录下创建文件夹的方法 xff0c
  • 详述 Mac GoLand 安装后打不开(闪退)的解决方法

    文章目录 现象描述解决方法Method 1Method 2 现象描述 安装了当前最新版 xff08 2021 2 3 xff09 的 GoLand xff0c 之前的版本是2019 2 5 xff0c 但比较诡异的是 xff1a 安装成功后
  • 使用 Golang 实现简易的令牌桶算法

    文章目录 简介实现轮子 简介 在网络中传输数据的时候时 xff0c 为了防止网络拥塞 xff0c 需限制流出网络的流量 xff0c 使流量以比较均匀的速度向外发送 令牌桶算法就实现了这个功能 xff0c 可控制发送到网络上数据的数目 xff
  • 详述 Git 的 rebase 命令使用方法

    在基于 Git 的开发过程中 xff0c 我们很容易遇到合并代码的情况 xff0c 例如我们从 master 分支拉取了一个 feature 分支 xff0c 当我们开发到一段时间之后 xff0c 可能需要将 master 的代码合并到我们
  • 使用 gomonkey 遇到非 debug 模式执行失败的问题及解决方法

    文章目录 问题描述解决方法 问题描述 基于 Golang 语言 xff0c 写单元测试 xff0c 使用gomonkey对于某个函数进行 Mock xff0c 遇到如下问题 xff1a 使用 正常模式 执行单元测试 xff0c Patch不
  • 使用 gomonkey Mock 函数及方法

    文章目录 前言函数方法参考 前言 在 Golang 语言中 xff0c 写单元测试的时候 xff0c 不可避免的会涉及到对其他函数及方法的 Mock xff0c 即在假设其他函数及方法响应预期结果的同时 xff0c 校验被测函数的响应是否符
  • 使用 gomonkey Mock 函数及方法时遇到 panic: permission denied 的问题及解决方法

    文章目录 问题描述解决方法 问题描述 基于 Golang 语言 xff0c 使用 gomonkey 来 mock 函数及方法 xff0c 在 Mac 环境执行的时候 xff0c 遇到如下错误 xff1a span class token b
  • 详述 TCP 的 TIME_WAIT 状态要维持 2MSL 的原因

    文章目录 前言正文 前言 本文主要分析为什么 TIME WAIT 状态的持续时间是 2MSL 而不是 1MSL xff0c 3MSL 或其它的时长 xff0c 而不会详细描述为什么需要 TIME WAIT 状态 阅读本文需要的预备知识 xf