Skip to content

简述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) 为什么三次握手?

  • 必要性
  • 三次握手确保双向通信可靠:
    1. 第一次(SYN):客户端确认自己能发送。
    2. 第二次(SYN+ACK):服务器确认自己能接收和发送,客户端确认自己能接收。
    3. 第三次(ACK):服务器确认自己能接收。
  • 三次交互完成序列号同步和双向能力验证。
  • 为什么不是两次?
  • 防止旧的、重复的连接请求(延迟的 SYN 包) 干扰新的连接建立。这种情况下,B 确认了 A 的 ISN(X),但 A 还没有向 B 确认收到了 B 的 ISN(Y)。这意味着从 A 到 B 的通信可能是可靠的(因为 B 知道 A 的起始序号),但从 B 到 A 的通信不是(因为 A 尚未确认 B 的起始序号),无法保证双向连接的可靠性。
  • 为什么不是四次?
  • 三次已足够,第四次无必要信息,增加延迟。
  • 第三次 ACK 可携带数据,优化效率。
  • 核心
  • 三次是确认双向通信的最小次数,平衡可靠性和效率。

(2) 为什么四次挥手?

  • 必要性
  • 四次挥手处理双向关闭,TCP 是全双工协议(双方可同时发送和接收),关闭需要分别确认:
    1. 主动方 FIN:表示主动方无数据发送。
    2. 被动方 ACK:确认收到主动方 FIN,进入半关闭。
    3. 被动方 FIN:表示被动方无数据发送。
    4. 主动方 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),清晰展示理解。