为什么需要 TIME_WAIT 状态

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 为什么需要 TIME_WAIT 状态

还是用一下上一篇文章画的图

TCP 的 11 个状态,每一个状态都缺一不可,自然 TIME_WAIT 状态被赋予的意义也是相当重要,咱们直接结论先行

上文我们提到 tcp 中,主动关闭的一边会进入 TIME_WAIT 状态,

另外 Tcp 中的有 TIME_WAIT 状态,主要是有如下 2 个原因:

  1. 为了防止被动关闭一方的延迟数据被其他连接窃取
  2. 为了防止被动关闭的一方,没有收到最后的一个 ACK 包

如何理解呢?

为了防止被动关闭一方的延迟数据被其他连接窃取

对于第一个

咱们一个一个的来详细解释一下,还是上面这个图,咱们人为的加一点异常的情况

咱们在 tcp 连接中,客户端先发起关闭,那么 TIME_WAIT 状态就在客户端这边,如下:

这是一个正常的客户端和服务端通信的基本过程,那么,如果在 client 和 server 建立连接后,server 端向 client 端发发送的数据,在网络环境中有延迟,短时间,没有顺利的达到 client 端的时候,就会出现如下情况

如上图

  • 我们人为的画了一个会出现在现实工作中的问题,当 client 和 server 正常连接,server 给 client 发的 seq=100 的包,由于网络拥堵等原因,留在了网络环境中
  • client 首先发起关闭连接,如果这个时候,没有 TIME_WAIT 状态,或者咱们人为的将 TIME_WAIT 的值设小,就会出现 seq=100 这个包不能正常的被 client 收到,因为 client 已经是 CLOSED 状态了
  • 这个时候,和 client 占用同一端口的程序 client 路人启动程序并和 server 成功建立连接之后,刚才的 seq=100 的包才到目的地址,这个时候 client 路人并不期望收到这个 seq=100 的消息,那么这对 client 路人来说,这就是一个异常问题了

如果咱们的 TIME_WAIT 状态存在,或者是正常保持 2MSL 的时间,就不会出现这个情况 ,1 个 MSL 是报文在网络环境中的最大存活时间,对于上面这个例子, client 现在那就还是 TIME_WAIT 状态, client 路人使用 client 的端口,是无法启动的,且 2MSL 的时间 seq=100 是完全可以达到 client 的

那是否会有人问,为什么 client 程序还在的时候,就不能启动 client 路人程序呢?

对于这个,咱们就需要知道 TCP 的一条连接,是由四元组组成的

  • 源地址
  • 源端⼝
  • ⽬的地址
  • ⽬的端⼝

此处我们知道,client 和 client 路人,源地址,目的地址,目的端口,都是一样的,那么此时如果源端口还是一样的话,那么是没有办法 2 个 client 都能正常启动的,其中一个正常启动了,那么另外一个就会报地址已经被使用

为了防止被动关闭的一方,没有收到最后的一个 ACK 包

再来看第二点

其实上面我们隐约已经说到了这一点,只不过不是 ack 包,再使用一下上面的图,我们人为的弄一个异常情况

如上图,当我们的 TIME_WAIT 状态不存在,或者设置的时间较小的时候,就可能会发生被动关闭的一方,收不到最后的一个 ack 包的情况

  • 一条 tcp 连接的四元组现在我们知道是啥意思了,那么,当上述 server 对应的连接还未是 CLOSED 状态的时候,server 是认为当前连接还是存在的
  • 但是 client 自身已经是 CLOSED 状态了,所以对于 client 路人来说,我当前的连接是有效的,因此我去给 server 发握手包
  • 可是万万没有想到,server 拒绝我的连接,client 路人就很蒙圈

此时,如果 TIME_WAIT 状态存在,并且等待的时间是 2MSL ,那么哪怕最后一个 ack 包丢失了,server 端也可以重新发送一个 FIN 包给到 client ,再等待一个新的 ack 包

这样,2 MSL 之后,client 和 server 端,对于这一条连接,都是正常关闭的

所以,为什么需要 TIME_WAIT 状态,心里有点数了不

感谢阅读,欢迎交流,点个赞,关注一波 再走吧

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

可以进入地址进行体验和学习:https://xxetb.xet.tech/s/3lucCI

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
网络协议 Cloud Native
为什么需要 TIME_WAIT 状态
TCP 的 11 个状态,每一个状态都缺一不可,自然 TIME_WAIT 状态被赋予的意义也是相当重要,咱们直接结论先行
114 1
|
NoSQL 算法 Redis
一日一技:除了 time.sleep,你还有一个暂停代码的方法
一日一技:除了 time.sleep,你还有一个暂停代码的方法
170 0
|
监控
实践解读CLOSE_WAIT和TIME_WAIT
实践解读CLOSE_WAIT和TIME_WAIT
386 0
实践解读CLOSE_WAIT和TIME_WAIT
|
测试技术 开发者
压测场景下的 TIME_WAIT 处理
压测场景下的 TIME_WAIT 处理
压测场景下的 TIME_WAIT 处理
|
弹性计算 网络协议 Java
记一次time_wait & close_wait的讨论总结
记一次time_wait & close_wait的讨论总结
记一次time_wait & close_wait的讨论总结
|
网络协议 测试技术
TIME_WAIT过多及解决
最近用http_load做压测,跑出来一大串“Cannot assign requested address ”的错误,查了一下,是TIME_WAIT过多导致的。因为短时间内有太多连接,所以占用了大量端口,同时关闭连接后又处于TIME_WAIT状态,端口不能复用,所以慢慢的无端口可用,所以就“Cannot assign requested address”了。
1107 1
|
数据采集 网络协议
一次TIME_WAIT和CLOSE_WAIT故障和解决办法
昨天解决了一个curl调用错误导致的服务器异常,具体过程如下: 里头的分析过程有提到,通过查看服务器网络状态检测到服务器有大量的CLOSE_WAIT的状态。   在服务器的日常维护过程中,会经常用到下面的命令:   它会显示例如下面的信息: TIME_WAIT 814CLOSE_WAIT 1FIN_WAIT1 1ESTABLISHED 634SYN_RECV 2LAST_ACK 1 常用的三个状态是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭。
2702 0
|
网络协议 测试技术 Go
|
网络协议 关系型数据库 MySQL