TCP三次握手与四次挥手
TCP三次握手与四次挥手[编辑 | 编辑源代码]
TCP三次握手(Three-way Handshake)和四次挥手(Four-way Handshake)是传输控制协议(TCP)建立和终止连接的核心机制。它们确保了数据传输的可靠性和有序性,是计算机网络中最重要的基础概念之一。
概述[编辑 | 编辑源代码]
TCP是一种面向连接的协议,在通信双方传输数据前,必须先建立连接,通信结束后再释放连接。三次握手用于建立连接,而四次挥手用于终止连接。
为什么需要握手和挥手?[编辑 | 编辑源代码]
- 可靠性:确保双方具备收发能力,避免无效连接。
- 同步序列号:交换初始序列号(ISN),保证数据有序传输。
- 资源管理:防止因网络延迟导致的历史连接干扰。
TCP三次握手[编辑 | 编辑源代码]
三次握手的目标是同步双方的初始序列号(ISN)并确认双方的收发能力。
握手过程[编辑 | 编辑源代码]
1. 第一次握手:客户端发送SYN=1(同步标志位)和初始序列号`seq=x`,进入`SYN_SENT`状态。 2. 第二次握手:服务器回复SYN=1、ACK=1(确认标志位),发送自己的序列号`seq=y`,并确认客户端的序列号`ack=x+1`,进入`SYN_RECEIVED`状态。 3. 第三次握手:客户端发送ACK=1,确认服务器的序列号`ack=y+1`,双方进入`ESTABLISHED`状态。
为什么是三次?[编辑 | 编辑源代码]
- 两次握手无法防止历史连接的干扰(如延迟的SYN包)。
- 三次握手可确保双方均确认对方的收发能力。
TCP四次挥手[编辑 | 编辑源代码]
四次挥手用于安全关闭连接,允许双方独立终止数据传输。
挥手过程[编辑 | 编辑源代码]
1. 第一次挥手:主动方(如客户端)发送FIN=1(终止标志位)和序列号`seq=u`,进入`FIN_WAIT_1`状态。 2. 第二次挥手:被动方(如服务器)回复ACK=1和确认号`ack=u+1`,进入`CLOSE_WAIT`状态。此时客户端进入`FIN_WAIT_2`状态。 3. 第三次挥手:被动方发送FIN=1和ACK=1,序列号`seq=v`,确认号`ack=u+1`,进入`LAST_ACK`状态。 4. 第四次挥手:主动方回复ACK=1和确认号`ack=v+1`,进入`TIME_WAIT`状态。等待2MSL(最大报文段生存时间)后关闭连接。
为什么是四次?[编辑 | 编辑源代码]
- TCP是全双工协议,双方需独立关闭通道。
- 被动方可能需要时间处理剩余数据(第二次挥手仅确认,第三次挥手才发送FIN)。
实际案例[编辑 | 编辑源代码]
网络抓包分析[编辑 | 编辑源代码]
使用Wireshark捕获的TCP握手数据示例(简化):
# 三次握手
1. Client → Server: [SYN] Seq=0
2. Server → Client: [SYN, ACK] Seq=0, Ack=1
3. Client → Server: [ACK] Seq=1, Ack=1
# 四次挥手
1. Client → Server: [FIN, ACK] Seq=1, Ack=1
2. Server → Client: [ACK] Seq=1, Ack=2
3. Server → Client: [FIN, ACK] Seq=1, Ack=2
4. Client → Server: [ACK] Seq=2, Ack=2
编程示例(Python socket)[编辑 | 编辑源代码]
# 服务端
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 8080))
s.listen(1)
conn, addr = s.accept() # 三次握手在此完成
conn.close() # 触发四次挥手
# 客户端
import socket
c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
c.connect(('127.0.0.1', 8080)) # 发起三次握手
c.close() # 发起四次挥手
常见问题[编辑 | 编辑源代码]
1. TIME_WAIT状态的作用?[编辑 | 编辑源代码]
- 确保最后一个ACK到达对端。
- 避免新旧连接混淆(等待2MSL使网络中残留报文失效)。
2. 握手能改为两次吗?[编辑 | 编辑源代码]
不能,可能因网络延迟导致连接冲突(如旧的SYN包突然到达)。
3. 挥手时为什么需要ACK和FIN分开发送?[编辑 | 编辑源代码]
因为被动方可能需要时间处理未发送完的数据(如服务器仍需发送响应)。
数学原理[编辑 | 编辑源代码]
初始序列号(ISN)的生成算法通常基于时钟和哈希函数,防止预测攻击: 其中`t`为时间,`H`为哈希函数。
总结[编辑 | 编辑源代码]
阶段 | 目的 | 关键标志位 |
---|---|---|
三次握手 | 建立可靠连接 | SYN, ACK |
四次挥手 | 安全终止连接 | FIN, ACK |
理解TCP握手和挥手机制对调试网络问题(如连接超时、端口占用)至关重要。实际开发中,可通过`netstat`命令观察连接状态。