TCP的三次握手、四次挥手

本文详细解析了TCP三次握手建立连接的过程及原因,包括各阶段的状态转换;并深入探讨了四次挥手关闭连接的机制,解释了为何需要四次挥手而非三次,以及TIME_WAIT状态的作用。

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

三次握手,建立连接

在这里插入图片描述

[CLOSED]	一开始服务器端和客户端都处于CLOSED状态
[CLOSED->LISTEN]	然后服务器端调用listen进入LISTEN状态,等待客户端连接

三次握手:客户端发送SYN、服务器端回复SYN+ACK、客户端回复服务器ACK

三次握手状态详解:
客户端:[CLOSED->SYN_SEND]	客户端调用connection,发送同步报文段SYN
服务器端:[LISTEN->SYN_ACVD]	服务器端监听到同步报文段SYN,将该连接放到等待队列,向客户端发送SYN+ACK确认报文 
客户端:[SYN_SEND->ESTABLISHED]客户端收到确认报文后状态转为ESTABLISHED,并向服务器端发送ACK	
服务器端:[SYN_ACVD->ESTBLISHED] 服务器端接收到确认报文,进入ESTABLISHED状态,连接已建立,可以进行读写数据了

为什么握手必须是三次?

1.服务器端无法通过SYN来确认客户端具有收发信息的能力
2.若SYN延迟,在收到一个SYN的情况下,服务器就会创建一个新的Socket。完整的状态保护可以避免对一个客户端创建多个Socket

若三次握手失败,服务端如何处理?

服务端超时等待ACK后,向客户端发送RST报文,然后释放新建的socket资源

四次挥手,关闭连接

在这里插入图片描述
四次挥手:客户端发送FIN、服务器端发送ACK、服务器端发送FIN、客户端发送ACK

四次握手状态详解: 
	注:一般客户端的FIN都是跟着DATA一起过去	
客户端:[ESTABLISHED->FIN_WAIT_1]	调用close同时,向服务器发送结束报文段FIN,进入FIN_WAIT_1
服务器端:[ESTABLISHED->CLOSE_WAIT]接收到结束报文段FIN,服务器返回确认报文段ACK,并进入CLOSE_WAIT
客户端:[FIN_WAIT_1->FIN_WAIT_2]接收到服务器端的确认报文段ACK,进入FIN_WAIT_2
服务器端:[CLOSE_WAIT->LAST_ACK] 进入CLOSE_WAIT说明服务器准备关闭连接(但是需要处理完最后一次的DATA),
		然后服务器真正调用close关闭连接时,向客户端发送结束报文段FIN,此时服务器进入LAST_ACK
客户端:[FIN_WAIT_2->TIME_WAIT]客户端收到服务器发来的ACK后进入TIME_WAIT,并向服务器发送最后的ACK
服务器端:[LAST_ACK->CLOSE]服务器接收到ACK后,彻底关闭连接
客户端:TIME_WAIT -> CLOSED] 客户端要等待⼀个2MSL(Max Segment Life, 报⽂最⼤⽣存时间)的时间,才会进⼊CLOSED状态

为什么挥手是四次?

被动端在接收到FIN之后进行ACK回复,但是不能直接关闭socket,因为此时用户有可能在处理数据(socket接收缓冲区中有可能还有堆积的数据),需要等用户来确认什么时候关闭socket发送FIN,一次ACK和FIN不能放在一起

为什么客户端不直接CLOSE,TIME_WAIT的作用是什么?

若没有TIME_WAIT,直接CLOSE,释放socket资源会造成的危害:
	假设被动关闭方最后一次ACK没有收到:
	此时主动关闭方以相同的地址立即重启
		(1)收到被动关闭方重传的FIN包,对新连接造成影响
		(2)主动关闭方方SYN请求,但是被动关闭方等待的是ACK,因状态不对对新连接造成影响
TIME_WAIT的作用:
	让主动关闭方等待一段时间,一般是2MLS。(MSL:报文最大生存时间)
	若被动关闭方重传FIN包,对其进行确认回复ACK
### TCP 三次握手四次挥手的过程及原理 #### 一、TCP 三次握手过程及原理 TCP 是一种面向连接的可靠传输协议,在数据传输前需要通过三次握手来建立连接。以下是其具体过程: 1. **第一次握手** 客户端向服务器发起连接请求,发送一个带有 SYN 标志位的数据包,并随机生成一个初始序列号 `Seq=x`,此时客户端进入 `SYN_SENT` 状态[^5]。 2. **第二次握手** 服务器收到客户端的 SYN 请求后,返回一个确认消息,该消息同时携带两个标志位:SYN 和 ACK。其中,SYN 表示同意建立连接并随机生成自己的初始序列号 `Seq=y`;ACK 则是对客户端序列号的确认,即 `Ack=x+1`。此时服务器进入 `SYN_RCVD` 状态[^4]。 3. **第三次握手** 客户端收到服务器的响应后,再次发送一个确认消息给服务器,此消息仅带有一个 ACK 标志位,用于确认服务器的序列号,即 `Ack=y+1`。随后,客户端进入 `ESTABLISHED` 状态,而服务器在接收到这个 ACK 后也进入 `ESTABLISHED` 状态,至此完成三次握手[^1]。 通过以上三个步骤,双方不仅建立了连接,还同步了各自的序列号和确认号,从而确保后续通信的可靠性[^3]。 --- #### 二、TCP 四次挥手过程及原理 由于 TCP 协议采用全双工模式工作,因此关闭连接时需分别处理双向通道的释放问题,这通常涉及四个阶段的操作,称为“四次挥手”。 1. **第一次挥手** 主动关闭的一方(通常是客户端)发送 FIN 报文通知对方自己已经没有数据要发送了,同时终止本方向上的数据流。此时,主动关闭方进入 `FIN_WAIT_1` 状态[^2]。 2. **第二次挥手** 被动关闭一方(通常是服务器)收到 FIN 报文后,回应一个 ACK 报文作为确认,设置 `Ack=seq+1`,并将被动关闭方的状态改为 `CLOSE_WAIT`。与此同时,主动关闭方则转变为 `FIN_WAIT_2` 状态[^4]。 3. **第三次挥手** 当被关闭方也没有更多数据待发时,它会再发送一个 FIN 报文告知主动关闭方准备完全断开连接。此时,被动关闭方变为 `LAST_ACK` 状态[^5]。 4. **第四次挥手** 主动关闭方接收到来自被动关闭方的 FIN 报文之后,回复最后一个 ACK 报文予以确认,然后进入 `TIME_WAIT` 状态。经过一段时间延迟(一般为两倍最大分组生存时间 MSL),如果未检测到异常情况,则正式关闭连接并转入 `CLOSED` 状态。同样地,被动关闭方在接受到最终 ACK 报文后立即切换至 `CLOSED` 状态,结束整个流程[^3]。 值得注意的是,“四次挥手”的核心在于允许两端独立管理各自方向上的资源回收,保障任何尚未送达的信息能够得到妥善处理[^2]。 --- ```python # Python模拟TCP三次握手四次挥手逻辑示意 class TCPSession: def __init__(self, client_seq, server_seq): self.client_seq = client_seq self.server_seq = server_seq def three_way_handshake(self): print(f"Client -> Server: SYN Seq={self.client_seq}") self.client_seq += 1 print(f"Server <- Client: SYN+ACK Ack={self.client_seq} Seq={self.server_seq}") self.server_seq += 1 print(f"Client -> Server: ACK Ack={self.server_seq}") def four_way_wavehand(self): print(f"Client -> Server: FIN Seq={self.client_seq}") print(f"Server <- Client: ACK Ack={self.client_seq + 1}") print(f"Server -> Client: FIN Seq={self.server_seq}") print(f"Client <- Server: ACK Ack={self.server_seq + 1}") session = TCPSession(0, 0) print("\n--- Three-Way Handshake ---") session.three_way_handshake() print("\n--- Four-Way Wavehand ---") session.four_way_wavehand() ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值