TCP三次握手与四次挥手
字数 2791 2025-11-02 08:11:07
TCP三次握手与四次挥手
描述
TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。为了建立一条可靠的连接,TCP使用了“三次握手”机制;为了终止连接,则使用了“四次挥手”机制。这是网络编程和互联网基础中至关重要的核心知识点。
解题过程/知识点讲解
我们将分两步来理解这个过程:首先是三次握手建立连接,然后是四次挥手终止连接。
第一步:理解TCP三次握手(连接建立)
三次握手的目标是通信双方确认彼此的发送和接收能力正常,并同步初始序列号(Sequence Number, SYN)。
-
第一次握手(SYN):
- 发起方(客户端) 想要与服务器建立连接。
- 动作:客户端发送一个TCP数据包。这个数据包的特点是:
- 其首部的SYN(同步)标志位被设置为1(即 SYN=1)。
- 它会随机选择一个初始序列号(seq = x)。序列号是保证数据按顺序传输的关键。
- 状态变化:发送后,客户端进入
SYN-SENT(同步已发送)状态。 - 含义:这个包像是在说:“你好服务器,我想和你建立连接。我的初始序列号是x,你听到了吗?”
-
第二次握手(SYN-ACK):
- 接收方(服务器) 收到了客户端的SYN包。
- 动作:服务器如果同意建立连接,会回复一个数据包。这个数据包的特点是:
- 首部SYN标志位和ACK(确认)标志位都设置为1(即 SYN=1, ACK=1)。
- 它也会随机生成自己的初始序列号(seq = y)。
- 同时,它会对收到的客户端序列号进行确认,其确认号(Acknowledgment Number, ack)字段设置为 x + 1(即 ack = x + 1)。
ack = x + 1的意思是:“我确实收到了你发来的序列号为x的包,我期望你下一次从序列号x+1开始发送数据。”
- 状态变化:发送后,服务器进入
SYN-RCVD(同步已收到)状态。 - 含义:这个包像是在说:“我听到了你的请求(ack=x+1),我同意建立连接。我的初始序列号是y,你听到了吗?”
-
第三次握手(ACK):
- 发起方(客户端) 收到了服务器的SYN-ACK包。
- 动作:客户端需要再次发送一个确认包。这个数据包的特点是:
- 首部ACK标志位设置为1(即 ACK=1)。
- 其序列号 seq = x + 1(因为第一次握手的SYN包消耗了一个序列号)。
- 其确认号 ack = y + 1,表示确认收到了服务器的SYN包。
- 状态变化:发送后,客户端进入
ESTABLISHED(连接已建立)状态。服务器收到这个ACK包后,也进入ESTABLISHED状态。 - 含义:这个包像是在说:“我也听到你的回复了,连接建立成功!”
为什么是三次,而不是两次?
关键在于防止“已失效的连接请求报文”突然传到服务器,导致服务器错误地打开连接。
- 场景:客户端发送了一个连接请求(第一个SYN),但这个包在网络中滞留了。客户端超时未收到回复,于是重发了一个SYN并成功建立连接、传输数据、关闭连接。此时,那个滞留在网络中的第一个SYN包终于到达了服务器。
- 如果是两次握手:服务器收到这个失效的SYN,会误以为客户端又发起了新连接,于是回复SYN-ACK(第二次握手)并直接进入
ESTABLISHED状态,开始等待客户端发送数据,从而白白浪费了服务器资源。 - 如果是三次握手:服务器回复SYN-ACK后,客户端会识别出这是一个失效的请求(因为它没有主动发起新连接),因此不会发送第三次的ACK确认。服务器由于收不到ACK,就不会建立连接,从而避免了资源浪费。
第二步:理解TCP四次挥手(连接终止)
四次挥手的目标是双方都确认要关闭连接。由于TCP连接是全双工的(数据可以双向流动),每个方向必须单独关闭。
-
第一次挥手(FIN):
- 主动关闭方(假设是客户端) 的数据已发送完毕,请求关闭连接。
- 动作:客户端发送一个数据包,其首部FIN(结束)标志位设置为1(FIN=1)。
- 状态变化:发送后,客户端进入
FIN-WAIT-1(终止等待1)状态。 - 含义:客户端对服务器说:“我这边没有数据要发送了,我想关闭我从你那里的数据通道(客户端到服务器的方向)。”
-
第二次挥手(ACK):
- 被动关闭方(服务器) 收到了客户端的FIN包。
- 动作:服务器发送一个确认包(ACK=1),其确认号 ack 为客户端序列号加1。
- 状态变化:发送后,服务器进入
CLOSE-WAIT(关闭等待)状态。 - 含义:服务器对客户端说:“哦,我知道你要关闭了。” 此时,TCP处于半关闭状态,即客户端到服务器的通道已关闭,客户端不能再发送数据,但服务器到客户端的通道仍然开放,服务器可能还有数据要发送给客户端。
- 客户端状态变化:客户端收到这个ACK后,从
FIN-WAIT-1进入FIN-WAIT-2(终止等待2)状态,等待服务器发送FIN包。
-
第三次挥手(FIN):
- 被动关闭方(服务器) 将剩余数据发送完毕后,也准备关闭连接。
- 动作:服务器发送一个数据包,其首部FIN标志位设置为1(FIN=1)。
- 状态变化:发送后,服务器进入
LAST-ACK(最后确认)状态。 - 含义:服务器对客户端说:“我这边数据也发完了,我也要关闭了(服务器到客户端的通道)。”
-
第四次挥手(ACK):
- 主动关闭方(客户端) 收到了服务器的FIN包。
- 动作:客户端发送一个确认包(ACK=1),其确认号 ack 为服务器序列号加1。
- 状态变化:发送后,客户端进入
TIME-WAIT(时间等待)状态。请注意,此时连接并未立即释放。客户端需要等待 2MSL(Maximum Segment Lifetime,最大报文段生存时间,通常为1-2分钟)的时间后,才进入CLOSED状态。 - 服务器状态变化:服务器收到这个ACK后,立即进入
CLOSED状态。
为什么客户端需要TIME-WAIT状态?等待2MSL是为了什么?
主要有两个原因:
- 可靠地终止连接:确保客户端发送的最后一个ACK能到达服务器。如果这个ACK在网络中丢失,服务器在
LAST-ACK状态下会因为超时而重传它的FIN包。客户端在TIME-WAIT状态下收到重传的FIN后,会重发ACK并重新计时等待2MSL。 - 让旧连接的报文在网络中消逝:等待2MSL时间,足以让本次连接过程中产生的所有报文都在网络中“消逝”(超过最大生存时间被丢弃),这样再建立新连接时,就不会受到旧连接报文的干扰。
通过以上循序渐进的步骤,我们就完整地理解了TCP如何通过三次握手可靠地建立连接,以及通过四次挥手优雅地终止连接。