mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
3722 字
10 分钟
QUIC与HTTP/3:传输层的性能革命
2022-07-14

TCP流控与拥塞控制 中,看到了 TCP 如何通过滑动窗口、慢启动和拥塞避免来保证可靠传输与公平性。但 TCP 的设计诞生于 1970 年代,那时的网络环境与今天截然不同——没有移动设备频繁切换网络,没有一个连接上承载几十个并发请求,也没有将加密视为必选项。TCP 的三个固有问题——传输层队头阻塞、握手延迟和连接迁移失败——在当代 Web 场景下越来越难以忍受。

QUIC 协议正是为解决这些问题而生。它基于 UDP与传输基础 中介绍的 UDP,在用户态重新实现了可靠传输、拥塞控制和多路复用,同时将加密作为协议的必选部分。HTTP/3 则将 HTTP 语义映射到 QUIC 之上,彻底消除了 HTTP/2 未能解决的队头阻塞问题。

本章从 TCP 的固有问题出发,深入 QUIC 的设计哲学、连接建立、流多路复用和连接迁移机制,再看 HTTP/3 如何在 QUIC 之上实现更高效的 Web 传输,最后通过动手实践观察真实的 QUIC 流量。

一、TCP的固有问题#

1.1 传输层队头阻塞#

TCP流控与拥塞控制 中看到,TCP 将数据视为一个有序的字节流。如果字节流中某个段丢失,后续所有已到达的段都必须在接收缓冲区等待重传——即使这些段属于完全不同的应用层请求。

HTTP/2 在 TCP 之上实现了多路复用,允许多个请求共享一个 TCP 连接。但这只解决了应用层的队头阻塞,传输层的队头阻塞依然存在:

flowchart TB subgraph TCP队头阻塞["TCP + HTTP/2:传输层队头阻塞"] direction TB TCP_SND["TCP 发送方"] TCP_RCV["TCP 接收方"] S1["Stream 1: 请求A<br/>段1 段2 段3 "] S2["Stream 2: 请求B<br/>段1 段2 段3 "] S3["Stream 3: 请求C<br/>段1 段2 段3 "] TCP_SND --> S1 & S2 & S3 S1 & S2 & S3 --> TCP_RCV BLOCK[" Stream 1 段2 丢失<br/>Stream 2、3 的数据已到达<br/>但 TCP 必须等待重传<br/>所有流都被阻塞!"] S1 -.->|"段2丢失"| BLOCK end subgraph QUIC无阻塞["QUIC + HTTP/3:无队头阻塞"] direction TB QUIC_SND["QUIC 发送方"] QUIC_RCV["QUIC 接收方"] Q1["Stream 1: 请求A<br/>段1 段2 段3 "] Q2["Stream 2: 请求B<br/>段1 段2 段3 "] Q3["Stream 3: 请求C<br/>段1 段2 段3 "] QUIC_SND --> Q1 & Q2 & Q3 Q1 & Q2 & Q3 --> QUIC_RCV NOBLOCK["Stream 1 段2 丢失<br/>仅 Stream 1 等待重传<br/>Stream 2、3 正常交付<br/>流间互不影响!"] Q1 -.->|"段2丢失"| NOBLOCK end style TCP队头阻塞 fill:#ffebee,stroke:#c62828 style QUIC无阻塞 fill:#e8f5e9,stroke:#2e7d32 style BLOCK fill:#ffcdd2,stroke:#c62828 style NOBLOCK fill:#c8e6c9,stroke:#2e7d32

一次 0.1% 的丢包率在 HTTP/2 下可能导致全部请求延迟增加数十毫秒,因为所有流共享同一个 TCP 的重传队列。

1.2 握手延迟#

TCP 连接建立需要三次握手(1-RTT),TLS 1.3 在此基础上还需要 1-RTT 完成密钥交换。一个全新的 HTTPS 连接需要 2-RTT 才能发送第一个应用数据:

阶段往返次数累计延迟
TCP 三次握手(SYN → SYN-ACK → ACK)1-RTT1-RTT
TLS 1.3 握手(ClientHello → ServerHello + 证书 + Finished)1-RTT2-RTT
发送 HTTP 请求02-RTT

对于 RTT 为 50ms 的连接,用户需要等待 100ms 才发出第一个请求。移动网络 RTT 更高,延迟更显著。

1.3 连接迁移失败#

TCP 连接由四元组标识:{源IP, 源端口, 目的IP, 目的端口}。当用户从 WiFi 切换到 4G,源 IP 地址改变,TCP 连接立即失效——必须重新建立连接,重新经历握手和 TLS 协商。

在移动场景下,这种”网络切换=连接中断”的行为严重影响用户体验:视频通话卡顿、下载中断、页面白屏重新加载。

Note

TCP 的这三个问题并非实现缺陷,而是协议设计的时代局限。TCP 被设计为在固定网络中提供可靠字节流,而今天的网络需要的是:多路复用、低延迟建立、移动性支持。修补 TCP 的成本远高于设计新协议——这就是 QUIC 诞生的根本原因。

二、QUIC的设计哲学#

2.1 基于UDP的用户态协议#

QUIC 选择在 UDP 之上实现,而非修改 TCP。这不是偷懒,而是务实的工程选择:

  • 内核协议栈难以演进:TCP 实现在操作系统内核中,修改需要升级内核,部署周期长达数年
  • 中间盒僵化:NAT、防火墙等中间盒对 TCP 报文有固定假设,任何 TCP 头部扩展都可能被丢弃
  • UDP 穿透性好:绝大多数中间盒允许 UDP 流量通过(DNS、WebRTC 等已验证)
  • 用户态快速迭代:QUIC 可以在应用层库中实现,无需等待操作系统更新

2.2 加密是必选项#

与 TCP 明文传输不同,QUIC 将加密作为协议的必选部分——几乎所有 QUIC 帧(除少数版本协商帧外)都经过 TLS 1.3 加密。这意味着:

  • 协议元数据(帧类型、流 ID 等)对中间盒不可见,避免了中间盒干扰
  • 省去了 TCP + TLS 的分层开销,握手和传输参数协商合并进行
  • 安全性不再是可选功能,而是协议的固有属性

2.3 连接ID实现迁移#

QUIC 引入连接 ID(Connection ID) 来标识连接,替代 TCP 的四元组。连接 ID 由端点独立生成,不随网络路径变化。当 IP 地址改变时,只要连接 ID 不变,连接就能继续——这就是连接迁移的基础。

2.4 流的独立性与多路复用#

QUIC 在传输层原生支持多路复用。每个流(Stream)有独立的流 ID,流内数据有序,但流与流之间互不阻塞。一个流的丢包重传不会影响其他流的数据交付。

TCP 与 QUIC 的核心差异对比:

特性TCPQUIC
传输层协议内核实现用户态(基于 UDP)
多路复用不支持(需 HTTP/2)原生支持(流)
队头阻塞传输层存在仅流内,流间无阻塞
加密可选(TLS 叠加)必选(TLS 1.3 集成)
连接标识四元组 {IP, 端口}连接 ID
连接迁移不支持支持
握手延迟TCP 1-RTT + TLS 1-RTT1-RTT(首次)/ 0-RTT(恢复)
拥塞控制内核实现(Cubic/BBR)用户态实现(可插拔)
头部扩展困难(中间盒干扰)灵活(加密保护)
丢包检测3 个重复 ACK / RTO更精确的 ACK + 包序号单调递增

三、QUIC连接建立#

3.1 1-RTT握手(首次连接)#

QUIC 将传输握手与 TLS 1.3 握手合并——在同一个往返中同时完成密钥交换和传输参数协商。客户端在第一个包中就发送 TLS ClientHello,服务端在响应中同时完成 TLS ServerHello 和传输参数协商:

sequenceDiagram participant C as 客户端 participant S as 服务端 Note over C,S: 首次连接:1-RTT 握手 C->>S: Initial[0]: CRYPTO(ClientHello)<br/>传输参数初始值 S->>C: Initial[0]: CRYPTO(ServerHello + 证书 + Finished)<br/>传输参数协商完成 Note over C,S: 1-RTT 后密钥协商完成 C->>S: Handshake: CRYPTO(Finished)<br/>1-RTT 数据: STREAM 请求 S->>C: 1-RTT 数据: STREAM 响应 Note over C,S: 连接建立完成,数据传输中

与 TCP + TLS 1.3 的 2-RTT 相比,QUIC 首次连接只需 1-RTT 即可发送应用数据。

3.2 0-RTT握手(恢复连接)#

当客户端之前与服务端建立过连接时,可以使用保存的会话票据(Session Ticket)发起 0-RTT 连接——在第一个包中就携带应用数据:

# 使用 curl 发起 HTTP/3 0-RTT 请求
# 首次连接(1-RTT)
curl --http3 https://example.com -v
# 恢复连接(0-RTT)——会话票据被缓存后
curl --http3 https://example.com -v
# 观察输出中的 "0-RTT" 标记
Warning

0-RTT 数据存在重放攻击风险。攻击者可以截获 0-RTT 数据并重放,导致服务端执行重复操作(如重复支付)。因此 0-RTT 仅适用于幂等请求(GET、查询),不适用于有副作用的操作(POST、转账)。QUIC 协议要求服务端检测并拒绝 0-RTT 重放。

3.3 传输参数与加密握手集成#

QUIC 的传输参数(如最大流数量、初始流量控制窗口等)在 TLS 握手的 CRYPTO 帧中传递,与密钥交换同步完成。这避免了 TCP + TLS 中传输参数需要额外协商的问题。

# 使用 qlog 查看 QUIC 传输参数
# qlog 是 QUIC 的标准化调试日志格式
cat connection.qlog | jq '.traces[0].events[] | select(.name == "transport:parameters_set")'
# 输出示例:
# {
# "name": "transport:parameters_set",
# "data": {
# "initial_max_streams_bidi": 100,
# "initial_max_data": 1048576,
# "initial_max_stream_data_bidi_local": 262144,
# "initial_max_stream_data_bidi_remote": 262144,
# "max_idle_timeout": 30000,
# "active_connection_id_limit": 4
# }
# }

四、QUIC流多路复用#

4.1 流的类型#

QUIC 定义了四种流类型,通过流 ID 的最低两位区分:

流 ID 最低位类型方向说明
0b00 (0)客户端发起的双向流双向客户端请求/响应
0b01 (1)服务端发起的双向流双向服务端推送(HTTP/3 未使用)
0b10 (2)客户端发起的单向流客户端→服务端QPACK 编码器指令
0b11 (3)服务端发起的单向流服务端→客户端QPACK 解码器指令、Push

流 ID 从 0 开始递增:第一个客户端双向流 ID 为 0,第二个为 4,第三个为 8——同一类型的流 ID 间隔为 4。

4.2 流间无队头阻塞#

QUIC 流的核心优势在于:每个流独立进行流量控制和可靠性保证。当 Stream A 的某个包丢失时:

  • Stream A 的后续数据在该流内等待重传
  • Stream B、C、D 的数据正常交付给应用层
  • 传输层 ACK 机制可以精确报告每个流的接收状态
# 使用 Wireshark 过滤 QUIC 流
# 查看特定流 ID 的数据
quic.stream.stream_id == 0
# 查看所有 STREAM 帧
quic.frame.type == 0x08
# 查看 QUIC 连接的流统计
quic && quic.frame.type == 0x08 | statistics

4.3 每流流量控制#

QUIC 为每个流和整个连接分别维护流量控制窗口:

  • 流级流量控制:限制单个流上发送方可以发送的未确认数据量
  • 连接级流量控制:限制所有流合计的未确认数据量

流量控制窗口通过 MAX_STREAM_DATAMAX_DATA 帧动态调整,机制与 TCP流控与拥塞控制 中的滑动窗口类似,但粒度更细。

五、连接迁移#

5.1 连接ID机制#

QUIC 连接的每个端点可以生成多个连接 ID。连接 ID 在握手期间通过 NEW_CONNECTION_ID 帧交换,用于以下场景:

  • 路径验证:验证新路径的对端可达性
  • 连接迁移:IP 地址变化时,用连接 ID 标识同一连接
  • 隐私保护:定期更换连接 ID,防止跨路径追踪
flowchart LR subgraph 迁移前["迁移前:WiFi 网络"] C1["客户端<br/>IP: 192.168.1.5<br/>CID: 0xA1B2"] S1["服务端<br/>IP: 93.184.216.34<br/>CID: 0xC3D4"] C1 -->|"UDP: 192.168.1.5:54321 → 93.184.216.34:443<br/>CID: 0xA1B2 → 0xC3D4"| S1 end subgraph 迁移后["迁移后:4G 网络"] C2["客户端<br/>IP: 10.20.30.40<br/>CID: 0xE5F6(新CID)"] S2["服务端<br/>IP: 93.184.216.34<br/>CID: 0xC3D4"] C2 -->|"UDP: 10.20.30.40:54321 → 93.184.216.34:443<br/>CID: 0xE5F6 → 0xC3D4"| S2 end 迁移前 -->|"WiFi → 4G 切换<br/>IP 变化,CID 标识连接<br/>无需重新握手"| 迁移后 style 迁移前 fill:#e3f2fd,stroke:#1565c0 style 迁移后 fill:#e8f5e9,stroke:#2e7d32

5.2 迁移过程#

当客户端检测到本地 IP 地址变化时:

  1. 使用新的源 IP 地址发送包含连接 ID 的 QUIC 包
  2. 服务端通过连接 ID 识别这是已有连接,而非新连接
  3. 服务端发起路径验证(PATH_CHALLENGE / PATH_RESPONSE),确认新路径可达
  4. 迁移完成,数据在新路径上继续传输

整个过程无需重新握手、无需重新协商密钥,连接无缝迁移。

5.3 NAT重绑定#

NAT 重绑定是连接迁移的一种特例:客户端 IP 未变,但 NAT 设备重新分配了外部端口。QUIC 同样通过连接 ID 处理这种情况——服务端检测到源端口变化后,进行路径验证并更新路径映射。

# 模拟 NAT 重绑定场景
# 使用 iptables 修改源端口映射
sudo iptables -t nat -A POSTROUTING -p udp --dport 443 \
-j SNAT --to-source 192.168.1.100:40000
# 观察服务端是否检测到路径变化
# 在 Wireshark 中过滤 PATH_CHALLENGE 帧
quic.frame.type == 0x1c || quic.frame.type == 0x1d

六、HTTP/3映射#

6.1 从HTTP/2到HTTP/3#

HTTP/3 保留了 HTTP 语义(方法、状态码、头部、Body),但将传输层从 TCP 换成了 QUIC。HTTP/2 与 HTTP/3 的关键差异:

特性HTTP/2HTTP/3
传输层TCPQUIC(基于 UDP)
队头阻塞传输层存在仅流内,流间无阻塞
头部压缩HPACK(静态/动态表)QPACK(静态/动态表 + 确认机制)
流 ID 分配奇偶区分客户端/服务端QUIC 流类型决定
优先级帧级优先级信号可扩展的优先级方案
连接建立TCP + TLS(2-RTT)QUIC(1-RTT / 0-RTT)
连接迁移不支持支持
TLS 版本TLS 1.2+TLS 1.3(必选)

6.2 QPACK头部压缩#

HTTP/3 使用 QPACK 替代 HTTP/2 的 HPACK 进行头部压缩。QPACK 的核心改进是解决 HPACK 在 QUIC 环境下的队头阻塞问题:

  • HPACK 的问题:动态表的更新依赖前序头部块的正确解码。如果前序流丢包,后续流无法解码动态表引用
  • QPACK 的解决方案:引入编码器到解码器的单向流,动态表更新通过确认机制(ACK)保证一致性,不依赖请求流的顺序
# QPACK 编码器流(客户端→服务端,流 ID = 0x2, 6, 10, ...)
# 传递动态表插入指令
# QPACK 解码器流(服务端→客户端,流 ID = 0x3, 7, 11, ...)
# 传递动态表确认(ACK)
# 在 Wireshark 中过滤 QPACK 帧
quic.stream.stream_id == 2 # 编码器流
quic.stream.stream_id == 3 # 解码器流

6.3 请求与响应映射#

HTTP/3 将每个 HTTP 请求/响应映射到一个 QUIC 双向流:

flowchart TB subgraph HTTP3请求响应["HTTP/3 请求/响应映射"] direction TB REQ1["请求 1<br/>GET /index.html<br/>Stream ID: 0"] REQ2["请求 2<br/>GET /style.css<br/>Stream ID: 4"] REQ3["请求 3<br/>GET /app.js<br/>Stream ID: 8"] RESP1["响应 1<br/>200 OK + HTML<br/>Stream 0"] RESP2["响应 2<br/>200 OK + CSS<br/>Stream 4"] RESP3["响应 3<br/>200 OK + JS<br/>Stream 8"] REQ1 -->|"HEADERS 帧<br/>DATA 帧"| RESP1 REQ2 -->|"HEADERS 帧<br/>DATA 帧"| RESP2 REQ3 -->|"HEADERS 帧<br/>DATA 帧"| RESP3 end subgraph 控制流["控制流"] CTRL["Stream ID: 2<br/>QPACK 编码器流"] DEC["Stream ID: 3<br/>QPACK 解码器流"] SETTINGS["Stream ID: 0(控制流)<br/>SETTINGS 帧"] end HTTP3请求响应 -.-> 控制流 style HTTP3请求响应 fill:#e3f2fd,stroke:#1565c0 style 控制流 fill:#fff3e0,stroke:#e65100

每个请求使用独立的 QUIC 流,流间互不阻塞。即使某个流的响应丢包,其他流的响应正常交付。

6.4 优先级#

HTTP/3 定义了更灵活的优先级方案(RFC 9218),使用 PRIORITY_UPDATE 帧在控制流上传递优先级信号。与 HTTP/2 的帧级优先级不同,HTTP/3 的优先级信号不嵌入请求流中,避免了优先级信号本身的队头阻塞。

七、动手实践:观察QUIC流量#

7.1 Chrome启用QUIC#

Chrome 默认对支持 HTTP/3 的站点启用 QUIC。可以通过以下方式控制和观察:

# 查看 Chrome 的 QUIC 状态
# 在地址栏输入
chrome://net-internals/#quic
# 强制启用 QUIC(如果默认关闭)
# 启动 Chrome 时添加标志
google-chrome --enable-quic --quic-version=h3-29
# 或在 chrome://flags 中搜索 QUIC 并启用
# chrome://flags/#enable-quic

chrome://net-internals/#quic 页面可以看到:

  • 当前活跃的 QUIC 会话列表
  • 每个会话的连接 ID、版本、本地/远端地址
  • 0-RTT 状态和流统计

7.2 Wireshark解析QUIC#

Wireshark 4.0+ 内置 QUIC 解析器,可以解密和显示 QUIC 帧:

# 基本过滤:显示所有 QUIC 包
quic
# 过滤 QUIC Initial 包(握手阶段)
quic.long.packet_type == 0
# 过滤 QUIC Handshake 包
quic.long.packet_type == 2
# 过滤特定连接 ID
quic.dcid == 0xa1b2c3d4e5f6
# 过滤 STREAM 帧
quic.frame.type == 0x08
# 过滤 CRYPTO 帧(TLS 握手数据)
quic.frame.type == 0x06
# 过滤 PATH_CHALLENGE / PATH_RESPONSE(连接迁移)
quic.frame.type == 0x1c || quic.frame.type == 0x1d
# 过滤 NEW_CONNECTION_ID 帧
quic.frame.type == 0x18

要解密 QUIC 流量,需要导出 TLS 密钥:

# 设置 SSLKEYLOGFILE 环境变量
export SSLKEYLOGFILE=/tmp/sslkeys.log
# 启动 Chrome(会自动写入 TLS 密钥)
google-chrome --enable-quic
# 在 Wireshark 中配置密钥日志
# Edit → Preferences → Protocols → TLS → (Pre)-Master-Secret log filename
# 指向 /tmp/sslkeys.log

7.3 curl使用HTTP/3#

curl 7.66+ 支持 HTTP/3,需要编译时启用 QUIC 支持:

# 检查 curl 是否支持 HTTP/3
curl --version | grep -i http3
# 发起 HTTP/3 请求
curl --http3 https://cloudflare-quic.com -v
# 输出中观察:
# * Connected to cloudflare-quic.com (104.16.132.229) port 443
# * SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
# * ALPN: server accepted h3
# > GET / HTTP/3
# < HTTP/3 200
# 仅使用 HTTP/3(不回退到 HTTP/2)
curl --http3-only https://cloudflare-quic.com -v
# 发送 0-RTT 数据
# 首次连接(保存会话票据)
curl --http3 -c /tmp/cookies.txt https://example.com
# 恢复连接(可能触发 0-RTT)
curl --http3 -b /tmp/cookies.txt https://example.com -v

7.4 qlog分析#

qlog 是 QUIC 的标准化调试日志格式(RFC 9257),提供连接事件的结构化记录:

# 安装 qlog 分析工具
npm install -g qlog-visualizer
# 使用 aQua(QUIC 分析工具)处理 qlog
# 从 Chrome 导出 qlog
# chrome://net-internals/#export-qlog
# 使用 qlog-visualizer 可视化
qlog-visualizer connection.qlog -o connection.html
# 使用 jq 分析 qlog 事件
# 查看连接建立事件
cat connection.qlog | jq '.traces[0].events[] |
select(.name == "connectivity:connection_started")'
# 查看丢包和重传事件
cat connection.qlog | jq '.traces[0].events[] |
select(.name == "recovery:packet_lost")'
# 查看流创建事件
cat connection.qlog | jq '.traces[0].events[] |
select(.name == "transport:stream_state_changed")'
# 查看 RTT 变化
cat connection.qlog | jq '.traces[0].events[] |
select(.name == "recovery:metrics_updated") |
{time: .time, rtt: .data.latest_rtt}'

7.5 Nginx配置QUIC#

Nginx 1.25.0+ 原生支持 QUIC 和 HTTP/3:

# nginx.conf - 启用 QUIC/HTTP/3
server {
listen 443 quic reuseport; # QUIC 监听(UDP)
listen 443 ssl; # TCP 回退
http2 on; # TCP 上使用 HTTP/2
server_name example.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
# TLS 1.3 必选
ssl_protocols TLSv1.3;
# 0-RTT 支持
ssl_early_data on;
# 通告客户端支持 HTTP/3
add_header Alt-Svc 'h3=":443"; ma=86400';
# QUIC 传输参数
quic_retry on; # 启用重试(防放大攻击)
quic_active_connection_id_limit 4;
location / {
proxy_pass http://backend;
}
}
# 验证 Nginx QUIC 配置
nginx -t
# 重载配置
nginx -s reload
# 测试 HTTP/3 连接
curl --http3 https://example.com -v
# 检查 UDP 443 端口是否监听
ss -ulnp | grep 443

八、本章小结#

QUIC 从根本上解决了 TCP 的三个固有问题,为现代 Web 传输带来了质的飞跃:

问题TCP 的局限QUIC 的解决方案
传输层队头阻塞字节流模型,一个丢包阻塞所有数据独立流多路复用,流间互不阻塞
握手延迟TCP 1-RTT + TLS 1-RTT = 2-RTT合并握手 1-RTT,恢复连接 0-RTT
连接迁移四元组标识,IP 变化即断连连接 ID 标识,IP 变化无缝迁移
加密可选叠加 TLS必选集成 TLS 1.3
协议演进内核实现,中间盒僵化用户态实现,加密保护扩展

HTTP/3 在 QUIC 之上重新映射了 HTTP 语义,用 QPACK 替代 HPACK 解决头部压缩的队头阻塞,用独立流实现真正的请求级多路复用。QUIC + HTTP/3 不是对 TCP + HTTP/2 的简单替换,而是传输层设计哲学的转变——从”内核实现、明文传输、连接绑定地址”到”用户态实现、加密必选、连接绑定 ID”。

QUIC 解决了传输层的性能瓶颈,但数据包在到达传输层之前,还需要将域名解析为 IP 地址——这就是 DNS 的工作。在 DNS域名系统 中,将看到域名如何通过层次化的分布式系统解析为 IP 地址,以及 DNSSEC 如何保证解析结果的可信性。


参考#

  • RFC 9218 — QUIC Loss Detection and Congestion Control
  • RFC 9257 — QUIC Version Negotiation

支持与分享

如果这篇文章对你有帮助,欢迎支持作者或分享给更多人

QUIC与HTTP/3:传输层的性能革命
https://blog.souloss.com/posts/internet-architecture/quic-and-http3/
作者
Souloss
发布于
2022-07-14
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

相关文章 智能推荐
1
系列导读
互联网运作 本系列从物理介质到应用层、从数据包离开网卡到抵达对端,用真实的包级追踪讲述互联网如何运作——物理编码、以太网交换、ARP首跳、IP寻址、NAT中间盒、域内域间路由、BGP安全、运营商骨干网、IXP互联、TCP/UDP/QUIC传输、DNS/TLS安全、HTTP演进、CDN分发、数据中心SDN、无线异构接入,每章配有Wireshark抓包与GNS3/FRR实验,让你从「会上网」进阶到「理解互联网」。
2
HTTP协议演进:从1.0到3.0的性能革命
互联网运作 从HTTP/0.9的单行请求到HTTP/3的QUIC传输,HTTP协议三十年演进的核心驱动力是什么?HTTP/1.1的持久连接与管道化、HTTP/2的二进制帧多路复用与HPACK、HTTP/3对TCP队头阻塞的彻底终结——每一代协议都在解决上一代的性能瓶颈。
3
UDP与传输基础:最简传输协议
互联网运作 数据包到达目的主机后如何交给正确的应用?传输层的角色、UDP报文格式与校验和、端口号与多路复用、UDP的应用场景与局限——从网络层到传输层的跨越。
4
TCP连接管理:三次握手与四次挥手的工程细节
互联网运作 TCP如何建立和释放连接?三次握手为什么不能是两次?四次挥手为什么不能是三次?TIME_WAIT到底在等什么?从报文格式到状态机,从SYN Flood防御到连接异常处理,用抓包实验观察TCP连接的完整生命周期。
5
TCP流控与拥塞控制:从滑动窗口到BBR
互联网运作 TCP连接建立之后,数据如何安全高效地传输?滑动窗口保护接收方不被淹没,拥塞控制保护网络不被压垮——从1986年拥塞崩溃到BBR模型驱动,理解TCP流量调控的完整演进。