TCP四次挥手

TCP四次挥手详解


文章目录

  • TCP四次挥手详解
    • 1. TCP四次挥手过程和状态变迁
    • 2. 为什么挥手需要四次?
    • 3. 为什么中间的ACK和FIN不可以像三次握手那样合为一个报文段呢?
    • 4. 为什么TIME_WAIT等待的时间是2MSL?
    • 5. 等待2MSL的意义
      • 5.1 保证客户端最后发送的ACK能够到达服务器,帮助其正常关闭。
      • 5.2 防止已失效的连接请求报文段出现在本连接中。
    • 6. TIME_WAIT状态过多有什么危害?


1. TCP四次挥手过程和状态变迁

在这里插入图片描述

在断开连接之前客户端和服务器都处于ESTABLISHED状态,双方都可以主动断开连接,以客户端主动断开连接为优。

第一次挥手: 客户端打算断开连接,向服务器发送FIN报文(FIN标记位被设置为1,1表示为FIN,0表示不是),FIN报文中会指定一个序列号,之后客户端进入FIN_WAIT_1状态。

也就是客户端发出连接释放报文段(FIN报文),指定序列号seq = u,主动关闭TCP连接,等待服务器的确认。

第二次挥手: 服务器收到连接释放报文段(FIN报文)后,就向客户端发送ACK应答报文,以客户端的FIN报文的序列号 seq+1 作为ACK应答报文段的确认序列号ack = seq+1 = u + 1。

接着服务器进入CLOSE_WAIT(等待关闭)状态,此时的TCP处于半关闭状态(下面会说什么是半关闭状态),客户端到服务器的连接释放。客户端收到来自服务器的ACK应答报文段后,进入FIN_WAIT_2状态。

第三次挥手: 服务器也打算断开连接,向客户端发送连接释放(FIN)报文段,之后服务器进入LAST_ACK(最后确认)状态,等待客户端的确认。

服务器的连接释放(FIN)报文段的FIN=1,ACK=1,序列号seq=m,确认序列号ack=u+1。

第四次挥手: 客户端收到来自服务器的连接释放(FIN)报文段后,会向服务器发送一个ACK应答报文段,以连接释放(FIN)报文段的确认序号 ack 作为ACK应答报文段的序列号 seq,以连接释放(FIN)报文段的序列号 seq+1作为确认序号ack。

之后客户端进入TIME_WAIT(时间等待)状态,服务器收到ACK应答报文段后,服务器就进入CLOSE(关闭)状态,到此服务器的连接已经完成关闭。

客户端处于TIME_WAIT状态时,此时的TCP还未释放掉,需要等待2MSL后,客户端才进入CLOSE状态。

由客户端到服务器需要一个FIN和ACK,再由服务器到客户端需要一个FIN和ACK,因此通常被称为四次挥手。

客户端和服务器都可以主动关闭连接,只有率先请求关闭的一方才会进入TIME_WAIT(时间等待状态)。

2. 为什么挥手需要四次?

这是由于TCP的半关闭(half-close)造成的。

半关闭: TCP提供了连接的一方在结束它的发送后还能接受来自另一端数据的能力。通俗来说,就是不能发送数据,但是还可以接受数据。

TCP不允许连接处于半打开状态时,就单向传输数据,因此完成三次握手后才可以传输数据(第三握手可以携带数据)。

当连接处于半关闭状态时,TCP是允许单向传输数据的,也就是说服务器此时仍然可以向客户端发送数据,等服务器不再发送数据时,才会发送FIN报文段,同意现在关闭连接。

这一特性是由于TCP双向通道互相独立所导致的,也使得关闭连接必须经过四次握手。

3. 为什么中间的ACK和FIN不可以像三次握手那样合为一个报文段呢?

在socket网络编程中,执行close()方法会触发内核发送FIN报文。什么时候调用close()方法,这是由用户态决定的,假如服务器仍有大量数据等待处理,那么服务器会等数据处理完后,才调用close()方法,这个时间可能会很久,而ACK报文则是由系统内核来完成的,这个过程会很快。所以中间的ACK和FIN不能合为一个包。

4. 为什么TIME_WAIT等待的时间是2MSL?

MSL(Maximum Segment LifeTime)是报文最大生成时间,它是任何报文在网络上存在的最长时间,超过这个时间的报文将被丢弃。

因为TCP协议是基于IP协议(位于IP协议的上一层),IP数据报中有限制其生存时间的TTL字段,是IP数据报可以经过的最大路由器的个数,每经过处理它的路由,TTL就会减一。TTL为 0 时还没有到达目的地的数据报将会被丢弃,同时发送 ICMP 报文通知源主机。

MSL的单位为时间,TTL的单位为跳转数。所以MSL应该大于等于TTL变为0的时间,以确保报文已被丢弃。

TIME_WAIT等待的2MSL时间,可以理解为数据报一来一回所需要的最大时间。

2MSL时间是从客户端接收到FIN后发送ACK开始计时的。如果在这个时间段内,服务器没有收到ACK应答报文段,会重发FIN报文段,如果客户端收到了FIN报文段,那么2MSL的时间将会被重置。如果在2MSL时间段内,没有收到任何数据报,客户端则会进入CLOSE状态。

5. 等待2MSL的意义

5.1 保证客户端最后发送的ACK能够到达服务器,帮助其正常关闭。

由于这个ACK报文段可能会丢失,使得处于LAST_ACK状态的服务器得不到对已发送FIN报文段的确认,从而会触发超时重传。服务器会重发FIN报文段,客户端能保证在2MSL时间内收到来自服务器的重传FIN报文段,从而客户端重新发送ACK应答报文段,并重置2MSL计数。

假如客户端不等待2MSL就之间进入CLOSE状态,那么服务器会一直处于LAST_ACK状态。

当客户端发起建立SYN报文段请求建立新的连接时,服务端会发送RST报文段给客户端,连接建立的过程就会被终止。

5.2 防止已失效的连接请求报文段出现在本连接中。

TIME_WAIT等待的2MSL时间,确保本连接内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。

6. TIME_WAIT状态过多有什么危害?

只有主动发起断开请求的一方才会进入TIME_WAIT状态!

  1. 占用系统资源
  2. socket的TIME_WAIT状态结束之前,该socket占用的端口号将一直无法释放。如果服务器TIME_WAIT状态过多,占满了所有端口资源,则会导致无法创建新的连接。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/18501.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux网络——Shell编程之数组

Linux网络——Shell编程之数组 一、概念二、数组的定义三、Shell数组操作1. 获取数组的所有元素的列表2. 获取数组的所有元素下标3.取数组的元素个数4. 获取数组的某个元素的值5.删除数组某个元素6.删除数组7.数组切片8.数组字符替换9.数组追加元素 四、数组在函数的传参 一、概…

天猫数据分析:2023年Q1天猫净水器品牌销售TOP10排行榜

水质的好坏更是与人们的身体健康密切相关。随着社会经济的发展,居民生活水平提升,人们对饮用水质量、安全性的要求也不断提高,净水器也因此逐渐成为现代生活的必需品。 根据鲸参谋电商数据显示,2023年Q1在天猫平台上,净…

3. SQL底层执行原理详解

一条SQL在MySQL中是如何执行的 1. MySQL的内部组件结构1.1 Server层1.2 Store层 2. 连接器3. 分析器4. 优化器5. 执行器6. bin-log归档 本文是按照自己的理解进行笔记总结,如有不正确的地方,还望大佬多多指点纠正,勿喷。 1. MySQL的内部组件结…

MVC分部视图的使用:Html.Partial/RenderPartial,Html.Action/RenderAction,RenderPage

ASP.NET MVC 里的部分视图,相当于 Web Form 里的 User Control。我们的页面往往会有许多重用的地方,可以进行封装重用。 使用部分视图有以下优点: 1. 可以简写代码。 2. 页面代码更加清晰、更好维护。 在视图里有多种方法可以 加载部分视图&a…

硬盘数据突然消失怎么回事?硬盘数据突然消失怎么找回

硬盘上的数据对每个人都至关重要,它可能是我们的珍贵回忆,多年学习的总结,或者一些不可告人的秘密。而硬盘中的数据可能会在不知情的情况下消失或被删除,这种情况对我们来说十分痛苦和困扰。然而,我们不必担心&#xf…

如何用100天彻底学会Python?

Python 是一门功能强大、易于学习且历史悠久的编程语言。如果你希望在短时间内彻底学会 Python,需要制定一个全面的学习计划,并进行刻意的练习和实践。 以下是一份建议的学习计划,帮助你在 100 天内掌握 Python 技能。 第 1-10 天&#xff…

JavaScript class和继承的原理

(对于不屈不挠的人来说,没有失败这回事。——俾斯麦) class 相关链接 MDN链接 有关类的详细描述 关于构造函数,原型和原型链的说明 类的概述 类是用于创建对象的模板。他们用代码封装数据以处理该数据。JS 中的类建立在原型上…

【Queue新技法】用双数组实现一个队列 C++

目录 1 常规的队列构建2 加入一些限制2-1形式化说明2-2 优化:平衡队列 附录0 双数组或双链表实现队列1 单链表与循环缓冲区实现队列3 参考资料 1 常规的队列构建 到火车站办理退票,排队的人构成队列。注意到有两个关键动作: 入队&#xff0c…

C++类和对象(上)

目录 一、类 1.1 类的引入 1.2 类的定义 1.3 类的访问限定符及封装 1.3.1 类的访问限定符 1.3.2 封装 1.4 类定义方式 1.4.1 声明和定义都放在类体里 1.4.2 类可以声明和定义分离 1.5 类的作用域 1.6 类的实例化 1.6.1 定义 1.6.2 计算类对象的大小 二、this指针…

华为OD机试真题 Java 实现【猜字谜】【2023Q2】

一、题目描述 小王设计了一人简单的清字谈游戏,游戏的迷面是一人错误的单词,比如nesw,玩家需要猜出谈底库中正确的单词。猜中的要求如 对于某个谜面和谜底单词,满足下面任一条件都表示猜中: 变换顺序以后一样的&…

【MySQL】索引

之前的select所采用的方式是遍历数据表进行查找,这种方式效率是比较低的,尤其是数据表汇总数据量比较大的时候,于是便有了索引,MySQL中的索引的作用就是为了快速获取数据 文章目录 1.索引简介2.索引的数据结构2.1 B-Tree2.2 Hash索引 3.索引的分类4.索引的语法5.SQL性能分析6.…

字节跳动发放年终奖,远超预期~

最近一段时间,国内互联网大厂接连公布年终奖情况,整个后厂村都洋溢在春节般的喜庆气氛里。 虽然由于各种各样的顾虑(主要是人员流失问题),大部分公司都将年终奖发放时间调整到了年中,但好饭不怕晚&#xf…

Java笔记_17(异常、File)

Java笔记_17 一、异常1.1、异常体系介绍1.2、编译时异常和运行时异常1.3、异常的作用1.4、异常的处理方式1.5、捕获异常的灵魂四问1.6、异常中的常见方法1.7、抛出处理1.8、异常-练习(键盘录入数据)1.9、自定义异常 二、File2.1、File的概述和构造2.2、F…

uboot 启动内核代码分析

0、uboot和内核区别 uboot的本质就是一个复杂点的裸机程序。内核本身也是一个"裸机程序“,和uboot、和其他裸机程序并没有本质区别。 区别就是操作系统运行起来后在软件上分为内核层和应用层,分层后两层的权限不同,在内存访问和设备操作…

离散化(算法)

目录 一、离散化的概念二、离散化的模板三、离散化的应用题目思路分析代码实现 一、离散化的概念 离散化是一种将连续数据映射到离散值的过程。它通常用于优化某些算法,尤其是与区间查询相关的问题。 在离散化过程中,我们将一组实数转换为一组整数&#…

卫星下行链路预算模型(未完待续)

卫星下行链路预算模型 1. 接收端天线模型 简单一些,考虑地球同步卫星多波束通信系统,波束指向固定。波束数量为 N b N_b Nb​. 波束中心在地面的位置可以用经度向量和纬度向量表示: P ⃗ l g [ l 1 , l 2 , . . . , l N b ] P ⃗ l a [ a 1 , a 2 …

C++运算符重载

上一次我们说了其他的运算符&#xff0c;像 "" "" "" 等运算符的重载&#xff0c;但是在C中&#xff0c;我们还有一些运算符&#xff0c;<</>>就是流插入和流提取&#xff0c;以及我们上次说了其他的四个默认函数&#xff0c;剩余的…

EMC VNX登录Unisphere错误 certificate has invalid date问题处理

经常有用户反应说&#xff0c;突然用浏览器登录EMC VNX或者Clarrion CX系统的时候出现“certificate has invalid date”的故障&#xff0c;然后无法正常登录图形界面。具体报错如下图所示&#xff1a; 导致这个问题的原因在于VNX系统中的certification认证过期&#xff0c;既然…

DC-8通关详解

信息收集 漏洞发现 找个扫描器扫一下 msf试了几个exp都没用 那么手动找找 发现传参nid出存在sql注入 python sqlmap -u "http://192.168.45.144:80/?nid1" --union-cols1 -D d7db -T users -C name,pass --columns --tables --dump 用john爆密码 admin爆了20分钟没…

orin配置系统

查看linux下的opencv安装版本&#xff1a; pkg-config --modversion opencv查看linux下的opencv安装路径&#xff1a; sudo find / -iname "*opencv*"可知opencv安装在/usr/local/lib里面。 在~/.bashrc中配置如下 在刷机完成的Orin&#xff0c;执行如下命令以安装…
最新文章