TCP 三次握手
概述
- 定义:
- TCP 三次握手(Three-Way Handshake)是 TCP 协议在建立可靠连接时,客户端和服务器之间通过三次数据包交换确认双方通信能力的机制。
- 目的:
- 确保双方都能发送和接收数据。
- 同步双方的初始序列号(ISN),保证数据可靠传输。
- 避免旧连接的干扰(如延迟包)。
- 协议:
- 基于 TCP 头部标志位:SYN(同步)、ACK(确认)。
核心点
- 三次握手通过 SYN 和 ACK 交互,建立双向可靠连接。
1. 三次握手过程
三次握手涉及客户端和服务器的三个步骤,每个步骤发送一个 TCP 段。
(1) 第一次握手:客户端发送 SYN
- 描述:
- 客户端向服务器发送一个 SYN(同步)包,请求建立连接。
- 细节:
- TCP 头部标志:
SYN=1
。 - 初始序列号:
seq = x
(客户端的 ISN,随机生成)。 - 状态:
- 客户端:进入 SYN_SENT 状态。
- 服务器:未响应,处于 LISTEN 状态。
- 作用:
- 通知服务器客户端想建立连接,并提供初始序列号。
(2) 第二次握手:服务器响应 SYN+ACK
- 描述:
- 服务器收到 SYN,回复一个 SYN+ACK 包,确认客户端请求并发起自己的连接请求。
- 细节:
- TCP 头部标志:
SYN=1, ACK=1
。 - 服务器序列号:
seq = y
(服务器的 ISN,随机生成)。 - 确认号:
ack = x + 1
(确认客户端的序列号)。 - 状态:
- 服务器:进入 SYN_RECEIVED 状态。
- 作用:
- 确认客户端的 SYN。
- 请求客户端确认服务器的连接能力。
(3) 第三次握手:客户端发送 ACK
- 描述:
- 客户端收到 SYN+ACK,发送 ACK 包,确认服务器的请求。
- 细节:
- TCP 头部标志:
ACK=1
。 - 序列号:
seq = x + 1
(继续客户端序列)。 - 确认号:
ack = y + 1
(确认服务器的序列号)。 - 状态:
- 客户端:进入 ESTABLISHED 状态。
- 服务器:收到 ACK 后进入 ESTABLISHED 状态。
- 作用:
- 确认服务器的 SYN,完成连接建立。
图示
客户端 服务器
| SYN(seq=x) |
|--------------------------->|
| SYN+ACK(seq=y, ack=x+1) |
|<---------------------------|
| ACK(seq=x+1, ack=y+1) |
|--------------------------->|
2. 为什么需要三次握手
- 确保双向通信:
- 第一次:客户端能发送,服务器能接收。
- 第二次:服务器能发送,客户端能接收。
- 第三次:确认双方序列号同步。
- 可靠传输:
- 同步序列号(ISN)防止数据错序。
- 确保初始状态一致。
- 避免旧连接干扰:
- 两次握手可能导致旧 SYN 包建立错误连接。
- 三次握手通过第三次 ACK 验证连接有效性。
- 示例:
- 若只有两次握手,服务器发送 SYN+ACK 后无法确认客户端是否收到,可能浪费资源。
- 三次握手确保双方确认连接。
3. 实现细节
- TCP 头部:
- 包含标志位(SYN、ACK)、序列号(seq)、确认号(ack)。
- SYN 包携带选项(如 MSS、窗口大小)。
- 状态机:
- 客户端:CLOSED → SYN_SENT → ESTABLISHED。
- 服务器:LISTEN → SYN_RECEIVED → ESTABLISHED。
- 超时重传:
- 客户端发送 SYN 后,若未收到 SYN+ACK,触发重传(通常 3-6 次)。
- 源码相关(Linux 内核):
tcp_v4_connect
:客户端发起 SYN。tcp_v4_rcv
:服务器处理 SYN 和 ACK。
4. 常见问题
- 为什么不是两次握手?
- 两次无法确认客户端接收能力,可能导致服务器误认为连接建立。
- 旧 SYN 包可能引发错误连接。
- 为什么不是四次握手?
- 三次已足够确认双向通信,四次增加无谓开销。
- 半连接问题:
- 服务器收到 SYN 后进入 SYN_RECEIVED,若客户端不发 ACK,可能占用资源(SYN 洪水攻击)。
- 解决:SYN Cookie、队列限制。
5. 面试角度
- 问“过程”:
- 提三次步骤、标志位、序列号变化。
- 问“目的”:
- 提双向通信、序列号同步、防旧连接。
- 问“问题”:
- 提半连接、SYN 攻击。
- 问“图示”:
- 画流程图,标明 SYN、ACK、状态。
6. 总结
TCP 三次握手通过客户端发送 SYN、服务器回复 SYN+ACK、客户端发送 ACK,建立可靠连接。目的是同步序列号、确认双向通信、避免旧连接干扰。基于 TCP 头部标志和状态机实现,效率和可靠性兼顾。面试可提流程、图示或问题分析,清晰展示理解。