HTTP 握手¶
HTTP 本身没有应用层握手,但底层的 TCP 和 TLS 各自有独立的握手流程
核心概念¶
- TCP 三次握手 — 所有 HTTP 连接建立前的基础,客户端与服务器确认彼此收发能力
- TLS 握手 — HTTPS 场景下在 TCP 之上完成密钥协商和证书验证
- HTTP/2 SETTINGS 交换 — 应用层的"半个握手",双方协商连接参数
- QUIC 握手 — HTTP/3 将传输层和加密层合二为一,一次握手同时完成建连和加密
详解¶
TCP 三次握手¶
每次 HTTP 通信之前,底层都要先完成 TCP 三次握手:
sequenceDiagram
participant C as 客户端
participant S as 服务器
C->>S: SYN(我要连接)
S->>C: SYN-ACK(收到,我也准备好了)
C->>S: ACK(确认,开始传数据)
| 阶段 | 方向 | 标志位 | 作用 |
|---|---|---|---|
| 第一次 | 客户端 → 服务器 | SYN | 客户端发起连接请求 |
| 第二次 | 服务器 → 客户端 | SYN-ACK | 服务器确认并回应 |
| 第三次 | 客户端 → 服务器 | ACK | 客户端确认,连接建立 |
三次握手的本质是**双方各确认一次收发能力**,确保连接可靠。
TLS 握手(HTTPS)¶
在 TCP 握手之后、HTTP 请求之前完成:
| TLS 版本 | 握手耗时 | 说明 |
|---|---|---|
| TLS 1.2 | 2-RTT(两个来回) | 需要两次往返完成密钥协商 |
| TLS 1.3 | 1-RTT(一个来回) | 优化了握手流程 |
| TLS 1.3 0-RTT | 0-RTT | 恢复会话时无需额外往返 |
TLS 握手完成的事:
- 证书验证:确认服务器身份,防止中间人攻击
- 密钥协商:生成对称加密密钥
- 加密套件确定:双方商定使用的加密算法
HTTP/1.0 和 HTTP/1.1¶
这两个版本**没有应用层握手**——TCP 连上、TLS 握完,直接发 HTTP 请求。
HTTP/2 的 SETTINGS 交换¶
HTTP/2 在连接建立后有一个应用层初始化过程:
sequenceDiagram
participant C as 客户端
participant S as 服务器
Note over C,S: TCP + TLS 握手完成
C->>S: SETTINGS 帧(我的能力参数)
S->>C: SETTINGS 帧(我的能力参数)
C->>S: SETTINGS ACK
S->>C: SETTINGS ACK
Note over C,S: 可以开始发送请求了
双方通过 SETTINGS 帧交换参数,如最大并发流数、窗口大小等。这不算严格的"握手",但起到类似的协商作用。
HTTP/3 (QUIC)¶
HTTP/3 基于 QUIC 协议,QUIC 运行在 UDP 之上:
graph LR
A[QUIC] --> B[内置 TLS 1.3]
A --> C[内置可靠传输]
A --> D[多路复用]
A --> E[0-RTT 恢复]
- QUIC 把传输层握手和 TLS 1.3 握手**合二为一**
- 首次连接只需 1-RTT
- 恢复连接可达 0-RTT
- 解决了 TCP 的队头阻塞问题(单个流丢包不影响其他流)
各层握手对比¶
| 层级 | 协议 | 有握手? | 耗时 |
|---|---|---|---|
| 传输层 | TCP | ✅ 三次握手 | 1-RTT |
| 安全层 | TLS 1.2 | ✅ 密钥协商 | 2-RTT |
| 安全层 | TLS 1.3 | ✅ 密钥协商 | 1-RTT |
| 应用层 | HTTP/1.x | ❌ 无 | — |
| 应用层 | HTTP/2 | 半个(SETTINGS) | ~0.5-1 RTT |
| 传输+安全 | HTTP/3 (QUIC) | ✅ 内置 TLS 1.3 | 1-RTT / 0-RTT |
常见陷阱¶
误区:认为 HTTPS 只多了一次握手
HTTPS 的额外开销不仅是 TLS 握手本身。如果 CDN、代理层多,TLS 握手可能要打好几次。理解每一层的握手才能优化延迟。
0-RTT 并非免费
TLS 1.3 的 0-RTT 恢复虽然快,但存在**重放攻击**风险。0-RTT 发送的数据不能保证幂等性,因此不适合做敏感操作(如支付)。
练习题¶
为什么 TCP 握手是三次而不是两次?
答案
两次握手无法防止**已失效的连接请求**到达服务器。如果客户端的旧 SYN 延迟到达,服务器会误以为是新请求并建立连接,白白浪费资源。三次握手让客户端有最后一次确认的机会,丢弃过期请求。
HTTP/2 的 SETTINGS 交换和 TCP 三次握手有什么区别?
答案
TCP 三次握手发生在传输层,目的是建立可靠的字节流通道。HTTP/2 的 SETTINGS 交换发生在应用层,目的是协商 HTTP 协议参数(如最大并发流、窗口大小等)。TCP 握手解决的是"能不能通信",SETTINGS 解决的是"怎么高效通信"。