TCP四次挥手详解[通俗易懂]

TCP四次挥手详解[通俗易懂]在开始之前可以先了解一下TCP三次握手TCP四次挥手过程和状态变迁在断开连接之前客户端和服务器都处于ESTABLISHED状态,双方都可以主动断开连接,以客户端主动断开连接为优。第一次挥手:客户端打算断开连接,向服务器发送FIN报文(FIN标记位被设置为1,1表示为FIN,0表示不是),FIN报文中会指定一个序列号,之后客户端进入FIN_WAIT_1状态。也就是客户端发出连接释放报文段(FIN报文),指定序列号seq=u,主动关闭TCP连接,等待服务器的确认。第二次挥…

大家好,又见面了,我是你们的朋友全栈君。


在开始之前可以先了解一下     TCP三次握手


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

为什么挥手需要四次?

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

等待2MSL的意义

TIME_WAIT状态过多有什么危害?

如何解决TIME_WAIT状态过多?

TCP四次挥手详解[通俗易懂]


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

 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)报文段,之后服务器进入LASK_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(时间等待状态)。

为什么挥手需要四次?

这是由于TCP的半关闭(half-close)造成的。半关闭是指:TCP提供了连接的一方在结束它的发送后还能接受来自另一端数据的能力。通俗来说,就是不能发送数据,但是还可以接受数据。

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

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

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

可能有些人会有疑惑:为什么中间的ACK和FIN不可以像三次握手那样合为一个报文段呢?

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

为什么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状态。

等待2MSL的意义

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

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

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

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

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

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

TIME_WAIT状态过多有什么危害?

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

1.占用系统资源

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

如何解决TIME_WAIT状态过多?

最好的办法是尽量让客户端主动断开连接,除非遇到一些异常情况,如客户端协议错误、客户端超时等。

打开系统的TIME_WAIT重用和快速回收。

在Linux系统可以修改以下参数:

        1.打开TCP对时间戳的支持,保持服务器与客户端时间同步 

net.ipv4.tcp_timestamps=1(默认即为 1)

        2.修改net.ipv4.tcp_tw_reuse = 1,允许对处于TIME_WAIT的socket用于建立新的连接

net.ipv4.tcp_tw_reuse = 1 (默认为0)

修改TIME_WAIT连接状态的上限值,超过上限值,处于TIME_WAIT状态的socket将立刻被清除并打印警告信息。

net.ipv4.tcp_max_tw_buckets = 18000,表示系统同时保持处于TIME_WAIT状态的socket的最大数量,默认为18000。

可修改为更小值。

net.ipv4.tcp_max_tw_buckets = 6666

还有一个是修改短连接为长连接的方式(目前没有学到)。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/137124.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 微信小程序一个js文件读取多个接口数据「建议收藏」

    微信小程序一个js文件读取多个接口数据「建议收藏」我也不知道这个叫啥问题我也不知道这样写是不是不对数据确实拿到了data:{warningarr:null,mydata:null,mySensor:null},/***生命周期函数–监听页面加载*/onLoad:function(options){ ……/*自己的…

    2022年8月18日
    3
  • UDP Flood攻击「建议收藏」

    UDP Flood攻击「建议收藏」本文转载自华为企业互动社区大家好,强叔又来了!上一期,强叔给大家介绍了SYNFlood的攻击和防御,本期强叔将带领大家一起来学习一下另一种常见的流量型攻击:UDPFlood。讲UDPFlood之前,强叔还是先从UDP协议讲起。在讲SYNFlood的时候,我们知道了TCP协议是一种面向连接的传输协议。但是UDP协议与TCP协议不同,UDP是一个无连接协议。使用UDP协议传输数据之前…

    2022年10月2日
    0
  • 从机械硬盘和固态硬盘的结构来看IO

    从机械硬盘和固态硬盘的结构来看IO“磁盘”这个词,对于程序员来说并不陌生,我们知道它是一种存储介质,主要用来存储数据的,可以说常用的中间件基本上都离不开它,比如我们常用的MySQL数据库、kafka消息引擎,甚至redis缓存都离不开磁盘。我们在优化某个业务逻辑的时候,经常需要用到缓存,尽量让热数据都从缓存里读取,因为我们知道磁盘是缓慢的,特别在高并发的场景下,我们要保证极少的请求走磁盘IO。不知道你有没有思考过以下问题: 机械硬盘为什么慢? 机械硬盘有多慢? kafka也是写磁盘的,它却挺快的,为什么?..

    2022年5月12日
    40
  • 软件看门狗与硬件看门狗_电脑看门狗是什么意思

    软件看门狗与硬件看门狗_电脑看门狗是什么意思软件看门狗和硬件看门狗的作用和区别工业级无线路由器,作为无线组网中非常重要的设备,洞察客户应用场景,只要是关乎无线组网可靠性的需求,即使是最细微的技术应用都要做到极致,比如看门狗。为什么工业级无线路由器这么重视软硬件看门狗,今天我们就来看看软硬件看门狗区别。看门狗,又叫watchdogtimer,是一个定时器电路,一般有一个输入,叫喂狗,一个输出到MCU的RST端,MCU正常工作的时候,每隔…

    2022年10月24日
    0
  • 遗传算法(Genetic Algorithm)详解与实现「建议收藏」

    遗传算法(Genetic Algorithm)详解与实现「建议收藏」遗传算法(GeneticAlgorithm,GA)是受自然进化原理启发的一系列搜索算法。通过模仿自然选择和繁殖的过程,遗传算法可以为涉及搜索、优化和学习的各种问题提供高质量的解决方案。同时,它们类似于自然进化,因此遗传算法可以克服传统搜索和优化算法遇到的一些障碍,尤其是对于具有大量参数和复杂数学表示形式的问题。

    2025年5月25日
    0
  • 数据增强英文_数据加噪处理

    数据增强英文_数据加噪处理文章目录0.前言1.Cutout1.1.要解决什么问题1.2.用了什么方法1.3.效果如何1.4.还存在什么问题&可借鉴之处2.RandErasing2.1.要解决什么问题2.2.用了什么方法2.3.效果如何2.4.还存在什么问题&可借鉴之处3.Mixup3.1.要解决什么问题3.2.用了什么方法3.3.效果如何3.4.还存在什么问题&可借鉴之处4.Cutmix4.1.要解决什么问题4.2.用了什么方法4.3.效果如何4.4.还存在什么问题

    2022年9月25日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号