计算机网络——TCP四次挥手

本文详细阐述TCP连接关闭过程中的四次挥手,包括FIN_WAIT1、CLOSE_WAIT、LAST_ACK和TIME_WAIT状态,解释了每个阶段的作用,并讨论了出现这些状态的原因。同时揭示了客户端问题导致的连接保持及保活机制。

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

TCP的四次挥手(假设由客户端发起)

        首先客户端原先处于ESTABLISHED状态,然后客户端发送完信息后发送FIN给服务器,此后自己进入FIN_WAIT1状态。

        服务器原先处于ESTABLISHED状态,然后服务器接收到FIN之后回复ACK,接着进入CLOSE_WAIT状态。客户端接收到ACK后进入FIN_WAIT2状态。

        服务器处理完接收的数据之后发送FIN表示不再接收数据,请求关闭。接着进入LAST_ACK状态。

        客户端接收到FIN后回应ACK表示接收到,随后自己进入TIME_WAIT状态,等待2MSL后自动进入CLOSED状态。服务器接收到ACK后直接进入CLOSED状态。

为什么要有CLOSE_WAIT状态?

        当发送方没有数据要发送时,可能接收方任然有数据需要接收,或者有数据需要读或写,那么此时是不能立刻关闭客户端,此时就需要一个等待的时间。

为什么要有TIME_WAIT状态?

两个作用:

1.防止旧的数据包干扰下次连接

        TIME_WAIT状态需要等待2MSL,MSL是网络报文在网络上生存的最大时间,所以经过MSL之后,发送的所有数据包要么被接收了,要么就丢失了,不可能会有活的数据包发送到下次连接的。

2.确保连接正常关闭

        剩下的一个MSL就是确保接收方发送FIN的有足够的时间到达服务器,假设最后发送方回应的ACK经过MSL后丢失了,那么接收方就会重新发送FIN,在ACK丢失且新的FIN到达时的时间为MSL——2MSL。

建立连接后客户端出现问题会发生什么?

        此时连接任然继续,但是客户端无法发送包,所以此时处于相看两无言的一个状态。这种状态其实就是浪费时间,但是万一一定时间内客户端恢复了会怎么样,那么能直接断开吗?显然是不理性的,所有TCP就有一个保活机制。就是双方无数据交互时,在一定时间内双方会任然处于连接状态,当超过指定时间后,接收方就会给发送方发送一个探测报文,看看对方挂没挂,多次探测报文没有回应后就认为对方挂了,接收方提前进入CLOSED状态。

### TCP 连接建立与断开过程 #### 三次握手过程详解 TCP 使用三次握手来建立可靠的连接。具体过程如下: 当客户端希望与服务器建立通信时,会发送一个带有 SYN 标志的数据包给服务器,此时该数据包中的序列号设为 `x`。 服务器收到这个请求后,如果同意建立连接,则向客户端回送一个 ACK 报文作为应答,并设置确认序号为 `x+1` 同时也携带自己的初始序列号 `y` 和 SYN 标记[^1]。 最后一步是由客户端再次回应服务器一个 ACK 数据段,其中包含对服务器之前发送过来的序列号加一后的值即 `y+1` 来表示已经成功接收到了来自对方的信息并准备就绪可以开始传输实际数据了[^2]。 ```python # 客户端发起SYN请求 client.send(SYN, seq=x) # 服务端响应SYN/ACK server.receive(SYN, seq=x) server.send(ACK, ack=x + 1, seq=y, SYN=True) # 客户端完成第三次握手 client.receive(ACK, ack=x + 1, seq=y) client.send(ACK, ack=y + 1) ``` #### 四次挥手流程 对于终止一条已有的TCP连接来说,通常采用的是四步挥手的方式来进行操作。以下是具体的步骤描述: 一方(假设为客户方)先主动关闭连接并向另一方发送 FIN 控制位置位的数据报;接着等待被通知的一侧回复一个 ACK 应答信号以表明它收到了结束指示并且不再期待更多来自原方向上的新信息流[^3]。 随后被动关闭的那一边也会发出自己想要中断的意思表达也就是第二个 FIN 帧,与此同时还要附带有一个新的序列编号用于跟踪这条消息的状态变化情况;最终由最初提出切断提议者给出最后一个确认答复——第三个也是第四个 ACK 消息,以此正式宣告整个双向通讯链路彻底解除关系。 ```python # 主动关闭方发送FIN active_side.send(FIN, seq=a) # 被动关闭方返回ACK passive_side.receive(FIN, seq=a) passive_side.send(ACK, ack=a + 1) # 被动关闭方发送FIN passive_side.send(FIN, seq=b) # 主动关闭方返回ACK active_side.receive(FIN, seq=b) active_side.send(ACK, ack=b + 1) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aristocrat l

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值