一:首先奉上
TCP三次握手的过程
TCP三次握手的过程
TCP连接释放的过程:
TCP连接释放的过程
二:
1。为什么两次就建立连接还要三次握手呢?这主要是为了防止已失效的连接请求报文又突然传递服务器。
所谓“防止已失效的连接请求报文又突然传递服务器。”是这样一种情况:
A客户端发出连接请求,因为连接请求报文丢失而未等到确认。于是A再次重传了连接请求,建立了连接。数据传输完毕后,释放了连接。现在假设那第一个请求只是因为网路节点长时间滞留了,使得它在第二个连接释放后才到达B服务器,那么B会以为这是一个新的连接请求,于是就向A发了个连接确认,注意了:如果没有最后一次的确认B会一厢情愿的以为连接已经建立,可人家A同学一看那个B给的是什么呀!跟自己没关系,简单粗暴的丢掉。这时B孩子还傻傻的等着A给他发数据,就这样,B白白浪费的大把的时光和资源。
那B会一直傻等吗?当然不是,它的等待也是有限的,答案就是保活计时器。

2.为什么要有四次挥手的TIME_WAIT的状态?
(1)第一是为了保证最后一个的一个ACK报文能到达B。这个ACK报文有可能丢失,因而使得处在LAST_ACK状态得不到对已发送的FIN+ACK报文的确认,B会超时重传这个FIN+ACk ,而A就能在这TIME_WAIT时间(2MSL)里收到这个重传的报文,A就可以重传一次确认,如果没有这个TIME_WAIT, 那B重传的FIN_ACK,可A早就走了,自然不会再重发确认,这样B就无法按照正常步骤进入CLOSE 状态。
(2)第二是防止“已失效的报文连接请求”,A在TIME_WAIT中,经过这2MSL的时间,就可以使本链接持续的时间内产生的所有连接消失,这样就可以使下一个新的连接中不会出现这样旧的连接请求报文段。
2.2 聪明的你会发现谁先关闭谁就有一个TIME_WAIT的状态;
在linux的网络编程中,如果服务器如果先关闭,你会发现,现在想要立马再次启动服务器,就会报错说这个端口号被占用着,那就是因为有这个TIME_WAIT,2msl的时间.那么怎么解决 ?
解决:setsockopt()函数。在这就不多说了。

根据第三版《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状态应该持续的时长。

对于刚才说的第二点,如何理解TIME_WAIT状态持续2MSL的时间就可以避免前后两个使用相同四元组的连接中的前一个连接的报文干扰后一个连接呢?

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

TCP连接中的一端发送了FIN报文之后如果收不到对端针对该FIN的ACK,则会反复多次重传FIN报文,大约持续几分钟;

被动关闭处于LAST_ACK状态的一端在收到最后一个ACK之后不会发送任何报文,立即进入CLOSED状态;

主动关闭的一端在收到被动关闭端发送过来的FIN报文并回复ACK之后进入TIME_WAIT状态;

之所以TIME_WAIT状态需要维持一段时间而不是进入CLOSED状态,是因为需要处理对端可能重传的FIN报文或其它一些因网络原因而延迟的数据报文,不处理这些报文可能导致前后两个使用相同四元组的连接中的后一个连接出现异常(详见UNIX网络编程卷1的2.7节 第三版);

处于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报文将会有两种结局:

ACK报文在网络中丢失;如前所述,这种情况我们不需要考虑,因为除非多次重传失败,否则AB两端的状态不会发生变化直至某一个ACK不再丢失。

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://blog.csdn.net/lthirdonel/article/details/103015627
https://www.cnblogs.com/joker1937/p/12487776.html

网络基础问题整理:为什么TCP四次挥手最后需要TIME_WAIT状态?相关推荐

  1. TCP三次握手连接和TCP四次挥手及大量TIME_WAIT解决方法:

    1.TCP建立连接,三次握手 建立的TCP连接可靠的连接,必须经过三次握手建立连接才能正式通信彼此传输数数据. 客户端请求服务端建立连接 第一次握手:客户给服务发送一个请求报文SYN, 客户端的状态置 ...

  2. TCP 连接管理机制(二)——TCP四次挥手的TIME_WAIT、CLOSE_WAIT状态

    介绍三次握手的时候,着重了解的是三次握手过程中,应用层和传输层做了哪些工作:下面在了解四次挥手的时候,主要了解的是四次挥手的状态变化. 目录 一.四次挥手 1.第一次挥手 2.第二次挥手 3.第三次挥 ...

  3. TCP四次挥手讲解,结合网络不可靠性的讨论

    为什么写这篇文章 看了很多文章都没有把TCP的四次挥手将透彻,导致我有很多疑问,所以我就自己去看了<计算机网络>一书中对TCP四次挥手的详细流程. 其他文章的问题在于没有结合网络的不可靠性 ...

  4. 深入浅出TCP四次挥手 (多图详解)

    文章目录 前言 1.TCP的连接释放 2.TCP通过"四报文挥手"来释放连接 3.四次挥手图文详解 4.四次挥手文字总结 5.相关面试问题 前言 TCP三次握手和四次挥手是面试题的 ...

  5. TCP四次挥手不同情况的研究(正常状态,三次挥手,以及CLOSING和RST)

    文章目录 TCP四次挥手不同情况的研究 1.新手加油站 1.1 TCP四次握手流程图 1.2 TCP头部 1.3 四次握手流程详解 2.针对挥手不同情况的实验和研究 2.1 正常情况 2.2 三次挥手 ...

  6. tcp 四次挥手_TCP三次握手和四次挥手

    名词解释 SYN:发起一个新连接 ACK:确认序号有效 FIN:释放一个连接 1,TCP三次握手 第一次握手:客户端发送syn包(syn=x)到服务器,并进入SYN_SEND状态,等待服务器确认: 第 ...

  7. 经典面试题之 TCP三次握手 和 TCP四次挥手过程----详解

    TCP三次握手过程: 第一次握手:建立连接时,客户端发送syn包(seq=j)到服务器,并进入SYN_SENT状态,等待服务器确认:SYN:同步序列编号(Synchronize Sequence Nu ...

  8. 被面试官问懵:TCP 四次挥手收到乱序的 FIN 包会如何处理?

    摘要:收到个读者的问题,他在面试的时候,被搞懵了,因为面试官问了他这么一个网络问题. 本文分享自华为云社区<TCP 四次挥手收到乱序的 FIN 包会如何处理?>,作者:小林coding . ...

  9. 计算机网络之TCP四次挥手

    文章目录 计算机网络之TCP四次握手 1.TCP四次挥手过程 2.任何一方执行close()操作即可产生挥手操作为什么要等待呢 3.说说 TCP 四次挥手过程 4.TCP挥手为什么需要四次呢 5. T ...

最新文章

  1. ZooKeeper场景实践:(6)集群监控和Master选举
  2. IT小小鸟VS.小小小鸟:展翅,我们一起翱翔!
  3. 用户sa登陆失败 SQLServer 错误18456的解决方法
  4. Session的实现与存储
  5. (三)opencv_py之阈值处理
  6. Python风格总结: List sort()方法
  7. python中yield的使用(两分钟读懂)
  8. Delphi Android下包含第三方DEX
  9. 四川大学控制专业考研上岸经验分享择校与专业选择
  10. python做生物信息学分析_Python从零开始第五章生物信息学①提取差异基因
  11. EasyUI onSelect方法
  12. PHP获取钉钉审批,PHP获取钉钉考勤信息源代码
  13. 查找数据库指定数据的数据表和字段名称SQL语句
  14. 市政管网检测机器人收费标准_淮安市金湖县市政管道机器人检测怎么收费
  15. oracle clear buffer,Out 对象的 clearBuffer() 方法用来清除缓冲区里的数据,但并不把数据写到客户端。...
  16. 如何解决Win10上OneNote 2016的同步问题
  17. 基于微信电子书阅读小程序毕业设计毕设作品(6)开题答辩PPT
  18. 龙族幻想微信一区哪个服务器人多,龙族幻想哪个区人最多_龙族幻想哪个区人多一点...
  19. 电器企业网站建设-电器网站设计建设方案
  20. MySQL统计总数就用count,别花里胡哨的《死磕MySQL系列 十》

热门文章

  1. 挑战微信,必须先忘记微信
  2. 4月26号软件更新资讯合集....
  3. 高中计算机室名言,高中教室励志名言
  4. cad绘制正八边形_cad怎么绘制绘制八角凳图纸?
  5. 如何获取电脑桌面坐标,如何获取屏幕位置 超简单
  6. 基于深度学习的文本分类 3
  7. PHP echo用法集
  8. CF645C Enduring Exodus 题解
  9. 最全的图片懒加载的实现
  10. 基于MDKA5D31-EK_T70开发板的QT示例-demo01:LEDTimer