TCP四次挥手

本文详细解释了TCP四次挥手过程,包括每个阶段的作用,以及在三次和四次挥手丢失时的处理策略。重点讨论了TIME_WAIT状态的2MSL等待时间及其必要性,以及为何选择2MSL而非更长时长。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TCP四次挥手过程

  1. client 发送FIN包, 进入FIN_WAIT状态
  2. server 接收FIN包, 回复ACK, 进入Close_wait状态
  3. 等待服务端close函数,将资源都释放,发送FIN包 进入LAST_ACK状态
  4. 客户端接收到FIN包后,回复最后一个ACK,进入TIME_WAIT状态,2MSL后进入closed状态
  5. 服务端接收到ACK后 进入close状态,关闭链接

为什么需要四次挥手

四次挥手中有丢失会出现什么情况

第三次挥手丢失

当服务端进程处理完数据之后就会进行关闭连接,内核就会向客户端发送FIN报文表示请求关闭连接,之后服务端就会进入LAST_ACK状态,会等待客户端返回的ACK报文.

当服务端进程调用close函数的时候->数据处理完之后才可以关闭连接,内核没有权利替代服务端关闭连接,必须由服务端主动调用close函数来关闭连接

如果服务端一直没有收到客户端返回的ACK报文,那么就会触发超时重传,服务端会重传FIN报文,如果之后接收到了ACK,服务端进入closed状态,如果没有 会继续重传,达到重传次数 客户端还没有收到ACK报文,那么会等待一段时间一般是上一次报文发送时间的2倍, 如果还没有收到,服务端会主动关闭连接.

另外呢,如果是使用的close函数关闭的连接,如果超过时长tcp_fin_timeout限制一般为60s,不会一直处于FIN_WAIT_2状态,客户端会主动关闭连接.

第四次挥手丢失

当服务端处理完数据之后就会调用close函数来关闭连接,会给客户端发送FIN报文,服务端进入LAST_ACK状态,客户端收到之后会返回一个ACK报文,客户端进入Time_WAIT状态等待2MSL后进入close状态,服务端接收到最后一个ACK报文之后进入closed状态.

如果第四次挥手丢失,也就是客户端返回的ACK丢失,服务端就会触发超时重传机制,重传FIN报文,如果之后服务端接收到了ACK,服务端就会进入closed状态,如果没有, 会继续重传,达到重传次数服务端还没有收到客户端发来的ACK报文,那么会等待一段时间一般是上一次报文发送时间的2倍, 如果还没有收到,服务端会主动关闭连接

另外,客户端收到第三次挥手之后,客户端返回给服务端ACK报文,客户端就会进入TIME_WAIT状态,会等待2MSL,如果中途再次收到第三次挥手,会重置定时器, 当等待2MSL之后,客户端就会主动关闭连接进入closed状态.

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

首先说什么是MSL,TTL,以及两者的关系

MSL就是最大的报文生成时间,MSL是网络报文生存的最长时间,超过这个时间,报文将会被丢弃,因为TCP是基于IP协议的,TTL是经过路由器的最大跳数,每经过一个路由器,TTL就减一,当减到0的时候报文就会被丢弃,同时发送ICMP报文给源主机.

TTL 与 MSL的区别 : TTL是经过路由的最大跳数,MSL是报文生存的最长时间,要确保MSL>=TTL才能保证报文是正常消亡.

为什么要等待2MSL呢 ?

原因是 在网络中可能来自发送方发来的数据报,然后接收方要给对方一个响应. 这样报文一来一回的时间就是2MSL.

比如当最后一个ACK报文丢失(也就是第四次挥手丢失),服务器那边就会触发超时重传机制,重传FIN报文,当FIN报文到达客户端,客户端再回一个ACK响应,这样一来一回等待的时间是2MSL.

2MSL时长允许报文至少丢失一次,当ACK报文丢失的时候,重发的FIN会在第二个MSL到达客户端,这样TIME_WAIT状态就可以应对.2MSL是当第三次挥手到达客户端的时候就会开始计时,当中途FIN报文再次到达客户端,定时器就会被重置为2MSL.

为什么不是 4MSL或者8MSL呢 ?

由于丢包概率很小,加入丢包概率为1/100,那么第二次丢包就是1/10000, 所以我们可以忽略,性价比会更高.

为什么需要 TIME_WAIT 状态?

主要有两个原因

防止旧的报文进入了相同的四元组连接中
能够保证被动关闭方正常关闭.

<think>嗯,用户想了解TCP四次挥手的详细过程、原理和图解。首先我需要回忆一下TCP连接终止的过程。四次挥手发生在客户端和服务器要关闭连接的时候,对吧? 首先,四次挥手的基本步骤应该是这样的:主动关闭的一方发送FIN,然后对方确认,接着对方也发送自己的FIN,最后主动方再确认。但具体每个步骤的状态变化和报文内容需要准确描述。比如,第一次挥手是FIN=1的报文,然后第二次是ACK,第三次是对方的FIN,第四次是最后的ACK。 不过用户提到参考了三个引用,其中引用[2]和[3]详细解释了四次挥手的原因和过程。比如为什么需要四次而不是三次,这可能是因为TCP是全双工的,每个方向都需要单独关闭。所以主动关闭方发送FIN后,被动方可能还有数据要发送,所以先回复ACK,等数据发完再发自己的FIN。这时候主动方再回复ACK,这样总共四次。 另外,引用[2]提到TIME_WAIT状态要等待2MSL时间,这是为了确保最后的ACK能够到达被动方,同时让旧的报文在网络中消失,避免混淆新连接。这部分需要解释清楚,为什么是2MSL,以及MSL的定义是什么。 还有,用户可能对报文中的序列号和确认号感兴趣,比如引用[3]中的例子,FIN报文中seq=4655,ACK=1。这里要说明ACK是对之前接收的数据的确认,而FIN本身的序列号是独立递增的。可能需要用具体的例子来说明序列号的变化过程。 最后,用户可能需要图解来辅助理解,但由于是文字回答,可以用步骤描述来代替,并建议参考相关图解。同时,生成的相关问题需要覆盖TIME_WAIT的作用、为什么是四次挥手、2MSL的意义等,这些都是常见的面试题或学习重点。 需要注意的是,用户提供的引用中有三次握手的引用[1],但问题集中在四次挥手,所以主要参考引用[2]和[3]。还要确保回答中使用正确的中文术语,比如“传输控制块TCB”等,但可能不需要深入,保持解释的易懂性。 现在整理步骤,确保每个步骤的状态变化正确,比如从FIN_WAIT_1到FIN_WAIT_2,然后到TIME_WAIT,最后CLOSED。被动方则从CLOSE_WAIT到LAST_ACK,再到CLOSED。这些状态变迁需要准确无误地描述出来,帮助用户理解整个过程。</think>### TCP四次挥手过程与原理详解 #### 一、四次挥手基本流程 TCP四次挥手是关闭全双工连接的标准流程,步骤如下: 1. **第一次挥手**(主动关闭方 → 被动关闭方) 主动关闭方发送FIN报文,设置$FIN=1$,并携带序列号$seq=u$,表示不再发送数据,进入`FIN_WAIT_1`状态[^2]。 2. **第二次挥手**(被动关闭方 → 主动关闭方) 被动关闭方发送ACK报文,设置$ACK=1$,确认号$ack=u+1$,进入`CLOSE_WAIT`状态。主动关闭方收到后进入`FIN_WAIT_2`状态[^3]。 3. **第三次挥手**(被动关闭方 → 主动关闭方) 被动关闭方完成数据发送后,发送FIN+ACK报文,设置$FIN=1, ACK=1$,携带序列号$seq=w$和确认号$ack=u+1$,进入`LAST_ACK`状态。 4. **第四次挥手**(主动关闭方 → 被动关闭方) 主动关闭方发送ACK报文,设置$ACK=1$,确认号$ack=w+1$,进入
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值