简述TCP三次握手四次挥手。为什么握手是三次,挥手是四次?
1. 三次握手(Three-Way Handshake)
定义: - 三次握手是 TCP 建立连接的过程,通过三次报文交换确保客户端和服务器都能发送和接收数据,建立可靠的双向连接。
过程:
1. 客户端发送 SYN:
- 客户端发送 SYN=1, seq=x
(同步报文,初始序列号 x),请求建立连接。
2. 服务器响应 SYN+ACK:
- 服务器回复 SYN=1, ACK=1, seq=y, ack=x+1
(同步并确认,确认客户端序列号 x+1,发送自己的序列号 y)。
3. 客户端发送 ACK:
- 客户端发送 ACK=1, seq=x+1, ack=y+1
(确认服务器序列号 y+1),连接建立。
图示:
客户端 服务器
| SYN (seq=x) |
|------------------>|
| SYN+ACK (seq=y, |
| ack=x+1) |
|<------------------|
| ACK (seq=x+1, |
| ack=y+1) |
|------------------>|
作用: - 同步双方初始序列号(ISN)。 - 确认双向通信能力(客户端可发送/接收,服务器可发送/接收)。 - 防止旧连接干扰(通过随机 ISN)。
2. 四次挥手(Four-Way Handshake)
定义: - 四次挥手是 TCP 关闭连接的过程,通过四次报文交换确保双方数据传输完成,安全释放连接。
过程:
1. 主动方发送 FIN:
- 主动关闭方(假设为客户端)发送 FIN=1, seq=x
(结束报文,表示无数据发送)。
2. 被动方响应 ACK:
- 被动方(服务器)回复 ACK=1, seq=y, ack=x+1
(确认收到 FIN),进入半关闭状态。
3. 被动方发送 FIN:
- 服务器发送 FIN=1, seq=z
(表示服务器无数据发送)。
4. 主动方响应 ACK:
- 客户端回复 ACK=1, seq=x+1, ack=z+1
(确认收到 FIN),连接关闭。
图示:
客户端 服务器
| FIN (seq=x) |
|------------------>|
| ACK (seq=y, |
| ack=x+1) |
|<------------------|
| |
| FIN (seq=z) |
|<------------------|
| ACK (seq=x+1, |
| ack=z+1) |
|------------------>|
作用: - 确保双方数据传输完成(无残留数据)。 - 安全关闭连接,释放资源。 - 处理半关闭状态(一方关闭,另一方仍可发送)。
3. 为什么握手是三次,挥手是四次?
(1) 为什么三次握手?
- 必要性:
- 三次握手确保双向通信可靠:
- 第一次(SYN):客户端确认自己能发送。
- 第二次(SYN+ACK):服务器确认自己能接收和发送,客户端确认自己能接收。
- 第三次(ACK):服务器确认自己能接收。
- 三次交互完成序列号同步和双向能力验证。
- 为什么不是两次?:
- 防止旧的、重复的连接请求(延迟的 SYN 包) 干扰新的连接建立。这种情况下,B 确认了 A 的 ISN(X),但 A 还没有向 B 确认收到了 B 的 ISN(Y)。这意味着从 A 到 B 的通信可能是可靠的(因为 B 知道 A 的起始序号),但从 B 到 A 的通信不是(因为 A 尚未确认 B 的起始序号),无法保证双向连接的可靠性。
- 为什么不是四次?:
- 三次已足够,第四次无必要信息,增加延迟。
- 第三次 ACK 可携带数据,优化效率。
- 核心:
- 三次是确认双向通信的最小次数,平衡可靠性和效率。
(2) 为什么四次挥手?
- 必要性:
- 四次挥手处理双向关闭,TCP 是全双工协议(双方可同时发送和接收),关闭需要分别确认:
- 主动方 FIN:表示主动方无数据发送。
- 被动方 ACK:确认收到主动方 FIN,进入半关闭。
- 被动方 FIN:表示被动方无数据发送。
- 主动方 ACK:确认收到被动方 FIN,连接关闭。
- 半关闭状态(
CLOSE_WAIT
)允许被动方继续发送数据(如服务器发送剩余响应)。 - 为什么不是三次?:
- 无法合并被动方的 ACK 和 FIN:
- 被动方收到 FIN 后需确认(ACK),但可能仍有数据发送,需等待处理完后发送 FIN。
- 合并会导致被动方无法发送剩余数据,或强制关闭,丢失数据。
- 示例:客户端发送 FIN,服务器有数据未发完,需先 ACK,待数据发送完后再 FIN。
- 为什么不是两次?:
- 两次无法确认双方关闭,可能导致数据丢失或连接残留。
- 核心:
- 四次挥手支持全双工和半关闭,确保双方独立关闭,数据完整。
4. 关键点与注意事项
三次握手
- 可靠性:
- 防止旧连接干扰(随机 ISN)。
- 检测网络异常(如 SYN 丢失重试)。
- 性能:
- 增加 1.5 RTT(往返时间)延迟。
- 优化:TCP Fast Open(TFO)复用握手。
- 安全:
- SYN 洪水攻击:大量伪造 SYN 耗尽资源。
- 解决:SYN Cookie(服务器不保存状态)。
- 状态:
- 客户端:
CLOSED → SYN_SENT → ESTABLISHED
。 - 服务器:
CLOSED → LISTEN → SYN_RCVD → ESTABLISHED
。
四次挥手
- 可靠性:
- 确保数据传输完成(半关闭支持剩余数据)。
- 超时重传(如 FIN 丢失)。
- 性能:
- 增加 2 RTT 延迟。
- 优化:延迟 ACK(合并 ACK 和 FIN)。
- 状态:
- 主动方:
ESTABLISHED → FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED
。 - 被动方:
ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED
。 - TIME_WAIT:
- 主动方等待 2MSL(最大报文生存时间),确保最终 ACK 送达,防止旧连接干扰。
- 问题:高并发下 TIME_WAIT 过多。
- 解决:调整 MSL 或启用连接复用。
5. 面试角度
- 问“三次握手过程”:
- 提 SYN → SYN+ACK → ACK,说明序列号同步和双向确认。
- 问“四次挥手过程”:
- 提 FIN → ACK → FIN → ACK,强调半关闭和全双工。
- 问“为什么三次握手”:
- 提双向通信确认,两次不足(半开连接),四次多余,举丢失 SYN+ACK 示例。
- 问“为什么四次挥手”:
- 提全双工需独立关闭,ACK 和 FIN 不可合并,举服务器有数据示例。
- 问“异常处理”:
- 提 SYN 丢失(重试)、FIN 丢失(重传)、TIME_WAIT 作用(防止旧报文)。
- 问“优化”:
- 提 TFO、延迟 ACK、SYN Cookie、TIME_WAIT 调优。
6. 总结
- 三次握手:
- 过程:SYN → SYN+ACK → ACK。
- 作用:建立连接,同步序列号,确认双向通信。
- 为什么三次:最小次数确保可靠双向连接,两次不足(半开),四次多余。
- 四次挥手:
- 过程:FIN → ACK → FIN → ACK。
- 作用:关闭连接,确保数据完整,支持半关闭。
- 为什么四次:全双工需独立关闭,ACK 和 FIN 不可合并。
- 核心区别:
- 握手建立双向连接,三次足够;挥手关闭全双工连接,需四次处理半关闭。
- 面试建议:
- 提流程(图示)、原因(双向 vs 全双工)、状态机(SYN_SENT、TIME_WAIT)、异常(丢失重试)、优化(TFO、Cookie),清晰展示理解。