TCP连接的建立和断开过程是网络通信的核心机制,主要通过三次握手(Three-way Handshake)建立连接,通过四次挥手(Four-way Handshake)断开连接。以下是详细说明:
一、TCP连接建立:三次握手
目的:确保通信双方都能正常发送和接收数据,并同步初始序列号(Sequence Number)。
步骤详解:
-
第一次握手(SYN)
- 客户端发送一个TCP报文:
- 标志位:
SYN=1(表示请求建立连接) - 序列号(Seq):随机值
X(例如 Seq = 100)
- 标志位:
- 客户端进入
SYN_SENT状态。
- 客户端发送一个TCP报文:
-
第二次握手(SYN + ACK)
- 服务器收到
SYN后,回复确认报文:- 标志位:
SYN=1(表示同意建立连接) +ACK=1(确认客户端的SYN) - 序列号(Seq):随机值
Y(例如 Seq = 300) - 确认号(Ack):
X + 1(例如 Ack = 101)
- 标志位:
- 服务器进入
SYN_RCVD状态。
- 服务器收到
-
第三次握手(ACK)
- 客户端收到
SYN+ACK后,发送最终确认报文:- 标志位:
ACK=1 - 序列号(Seq):
X + 1(例如 Seq = 101) - 确认号(Ack):
Y + 1(例如 Ack = 301)
- 标志位:
- 服务器收到后,双方进入
ESTABLISHED状态,连接建立成功。
- 客户端收到
为什么需要三次握手?
- 两次握手的风险:若客户端的失效连接请求(SYN)延迟到达服务器,服务器会误认为新连接已建立,导致资源浪费。
- 第三次握手的作用:客户端确认服务器的响应有效,避免历史连接干扰。
二、TCP连接断开:四次挥手
目的:双方确认数据已发送完毕,安全关闭连接。
步骤详解:
假设客户端主动发起关闭:
-
第一次挥手(FIN)
- 客户端发送结束报文:
- 标志位:
FIN=1(表示请求关闭连接) - 序列号(Seq):当前值
P(例如 Seq = 500)
- 标志位:
- 客户端进入
FIN_WAIT_1状态。
- 客户端发送结束报文:
-
第二次挥手(ACK)
- 服务器收到
FIN后,回复确认报文:- 标志位:
ACK=1 - 序列号(Seq):当前值
Q(例如 Seq = 700) - 确认号(Ack):
P + 1(例如 Ack = 501)
- 标志位:
- 服务器进入
CLOSE_WAIT状态,客户端收到后进入FIN_WAIT_2状态。
注意:此时服务器可能还有未发送完的数据(半关闭状态)。
- 服务器收到
-
第三次挥手(FIN)
- 服务器完成数据发送后,发送自己的结束报文:
- 标志位:
FIN=1+ACK=1 - 序列号(Seq):
Q + 数据长度(例如 Seq = 750) - 确认号(Ack):仍为
P + 1(例如 Ack = 501)
- 标志位:
- 服务器进入
LAST_ACK状态。
- 服务器完成数据发送后,发送自己的结束报文:
-
第四次挥手(ACK)
- 客户端收到
FIN后,回复最终确认报文:- 标志位:
ACK=1 - 序列号(Seq):
P + 1(例如 Seq = 501) - 确认号(Ack):
Seq + 1(例如 Ack = 751)
- 标志位:
- 客户端进入
TIME_WAIT状态,等待 2MSL(Maximum Segment Lifetime)后关闭。 - 服务器收到
ACK后立即关闭连接。
- 客户端收到
关键问题解析:
-
为什么需要四次挥手?
TCP是全双工协议,双方需独立关闭自己的数据通道。- 客户端发送
FIN表示不再发送数据(但仍可接收)。 - 服务器可能仍需发送剩余数据,故先回复
ACK,再单独发送FIN。
- 客户端发送
-
TIME_WAIT状态的作用(等待2MSL):
- 确保最后一个ACK到达服务器:若服务器未收到ACK,会重发FIN,客户端可重新响应。
- 避免旧连接的数据包干扰新连接:等待所有网络中的残余数据包消亡(MSL通常为30秒-2分钟)。
三、连接状态变化示意图
客户端 服务器
| |
|-------- SYN (Seq=X) -------->| 【三次握手开始】
|<------- SYN+ACK (Seq=Y, Ack=X+1)|
|-------- ACK (Ack=Y+1) ------>| 【连接建立】
| |
|... 数据传输 ... |
| |
|-------- FIN (Seq=P) -------->| 【四次挥手开始】
|<------- ACK (Ack=P+1) -------| (半关闭)
| |
|<------- FIN (Seq=Q) ---------|
|-------- ACK (Ack=Q+1) ------>| 【连接关闭】
|(等待2MSL) |
| |
四、实际应用注意事项
-
SYN Flood攻击:攻击者伪造大量SYN请求但不回复ACK,耗尽服务器资源。
防御:启用SYN Cookies或限制半连接数。 -
大量TIME_WAIT连接:
- 原因:短连接频繁建立/关闭(如Web服务器)。
- 解决:调整内核参数(如
net.ipv4.tcp_tw_reuse)或使用连接池。
-
TCP Keepalive:
长时间空闲的连接可能被中间设备断开,可通过Keepalive探测对方存活状态。
总结
| 阶段 | 关键动作 | 目的 |
|---|---|---|
| 三次握手 | SYN → SYN+ACK → ACK | 同步序列号,确认双向通信能力 |
| 四次挥手 | FIN → ACK → FIN → ACK | 安全关闭双向数据通道 |
| TIME_WAIT | 客户端等待2MSL | 确保最后一个ACK被接收,清理残余数据 |
理解TCP连接/断开的细节,有助于诊断网络问题(如连接超时、端口占用)及优化高并发服务。