协议栈数据流全景分析

一次 HTTPS 请求从应用层到物理层的完整旅程,逐层追踪数据封装/解封装过程。 synthesis 页:跨 HTTP协议/TLS协议/TCP协议/DNS协议/ARP协议/ICMP协议 综合分析。

1. 全景拓扑:协议栈封装与解封装

先看一张协议栈全景图,自上而下是发送方的封装过程,自下而上是接收方的解封装过程,本文所有阶段都能在上面找到位置:

scss 复制代码
                          发送方(封装)                              接收方(解封装)
                          ──────────                                ──────────

  ┌─────────────────────────────────────┐
  │  应用层  HTTP 请求行+头部+体          │ ← 生成数据
  └────────────────┬────────────────────┘
                   │ +TLS Record 头(5B) +AEAD 标签(16B)
  ┌────────────────┴────────────────────┐
  │  安全层  TLS Record(AES-GCM 加密)   │ ← 加密
  └────────────────┬────────────────────┘
                   │ +TCP 头(20B)
  ┌────────────────┴────────────────────┐
  │  传输层  TCP 段(seq/ack/窗口/端口)  │ ← 分段
  └────────────────┬────────────────────┘
                   │ +IP 头(20B)
  ┌────────────────┴────────────────────┐
  │  网络层  IP 包(src/dst/TTL/协议)    │ ← 路由
  └────────────────┬────────────────────┘
                   │ +以太网帧头(14B) +FCS(4B)
  ┌────────────────┴────────────────────┐
  │  链路层  以太网帧(src MAC/dst MAC)  │ ← ARP 查询
  └────────────────┬────────────────────┘
                   │ 编码(8B/10B 或 PAM-4)
  ┌────────────────┴────────────────────┐
  │  物理层  电信号/光信号/无线电磁波     │ ← 物理传输
  └─────────────────────────────────────┘
                   │
                   ↓  ← 逐跳转发(路由器只处理到网络层)
                   │
  ┌─────────────────────────────────────┐
  │  物理层  → 链路层 → 网络层 → 传输层   │ ← 逐层解封装
  │  → TLS 解密 → HTTP 解析 → 应用代码    │ ← 校验+路由
  └─────────────────────────────────────┘

对照速记:应用层管"说什么",安全层管"加密说",传输层管"分段说",网络层管"送到哪",链路层管"下一跳",物理层管"怎么传"。

2. 场景:浏览器访问 www.example.com/page

2.0. 阶段 0:DNS 解析

ini 复制代码
浏览器 → 本地 DNS 解析器 → 根 → TLD → 权威 → 返回 IP

协议栈:
  应用层:DNS Query (www.example.com, type=A)
  传输层:UDP 头 (src=随机, dst=53)
  网络层:IP 头 (src=本机IP, dst=DNS服务器IP)
  链路层:以太网帧 (src=本机MAC, dst=网关MAC)
scss 复制代码
  DNS 解析流程拓扑:

  浏览器
    │
    ├── 本地缓存命中? ──是──▶ 返回 IP(0ms)
    │
    ├── 系统缓存命中? ──是──▶ 返回 IP(<1ms)
    │
    └── 向 DNS 服务器查询
          │
          ├── 递归查询:本地 → 根 → TLD(.com) → 权威(example.com)
          │
          └── 返回 IP(5~50ms)

专家视角 :DNS 查询在 HTTPS 请求之前发生------浏览器先解析域名拿到 IP,才能建 TCP 连接。DNS 走 UDP协议 是为了省握手开销,但 DoH/DoT 走 TCP协议/HTTPS协议 加密。

2.1. 阶段 1:TCP 三次握手

ini 复制代码
协议栈:
  传输层:TCP 头 (SYN, seq=ISN, src=随机端口, dst=443)
  网络层:IP 头 (src=本机IP, dst=服务器IP, TTL=64)
  链路层:以太网帧 (src=本机MAC, dst=网关MAC)
    ↓ ARP 查询网关 MAC(若缓存未命中)
  物理层:电信号/光信号
ini 复制代码
  TCP 三次握手时序:

  客户端                              服务器
    │                                   │
    │ ── SYN (seq=ISN_c) ──────────────▶│  第1次:我要连接
    │                                   │
    │ ◀── SYN+ACK (seq=ISN_s, ack=ISN_c+1) ──│  第2次:同意,我也要连接
    │                                   │
    │ ── ACK (ack=ISN_s+1) ────────────▶│  第3次:确认你的连接
    │                                   │
    │ ═══ 连接建立,可发数据 ════════════│

2.2. 阶段 2:TLS 握手

scss 复制代码
协议栈(TLS 1.3,1-RTT):
  应用层:TLS ClientHello (密码套件列表, key_share, SNI)
  传输层:TCP 头 (PSH+ACK, seq, ack)
  网络层:IP 头
  链路层:以太网帧
scss 复制代码
  TLS 1.3 握手时序(1-RTT):

  客户端                              服务器
    │                                   │
    │ ── ClientHello ──────────────────▶│  密码套件 + key_share + SNI
    │    (含 ECDHE 公钥)                │
    │                                   │
    │ ◀── ServerHello + 证书 + Finished │  选定套件 + key_share + 签名
    │    (含 ECDHE 公钥 + AEAD 密钥)    │
    │                                   │
    │ ── Finished ─────────────────────▶│  验证完成
    │                                   │
    │ ═══ 会话密钥协商完成,可发加密数据 │

2.3. 阶段 3:HTTP 请求

swift 复制代码
协议栈:
  应用层:HTTP 请求行 + 头部 + 体
    "GET /page HTTP/1.1\r\n"
    "Host: www.example.com\r\n"
    "Accept: text/html\r\n"
    "Cookie: session=abc123\r\n"
    "\r\n"
  ↓ TLS 加密(AES-GCM,会话密钥)
  安全层:TLS Record (加密的 HTTP 数据)
  ↓ TCP 分段(若 HTTP 请求 > MSS)
  传输层:TCP 段 (PSH+ACK, seq, ack, 窗口)
  ↓ IP 路由(查路由表,选出接口)
  网络层:IP 包 (src, dst, TTL, 协议=TCP)
  ↓ ARP 查询下一跳 MAC
  链路层:以太网帧 (src=出接口MAC, dst=下一跳MAC)
  ↓ 物理层编码(8B/10B 或 PAM-4)
  物理层:电信号/光信号/无线电磁波
swift 复制代码
  HTTP 请求逐层封装拓扑:

  ┌───────────────────────────────────────────────┐
  │ 应用层   "GET /page HTTP/1.1\r\nHost: ...\r\n" │  500B HTTP 体 + 300B 头
  └───────────────────────┬───────────────────────┘
                          │ TLS 加密(AES-GCM)
  ┌───────────────────────┴───────────────────────┐
  │ 安全层   TLS Record(5B头 + 密文 + 16B标签)    │  +21B 开销
  └───────────────────────┬───────────────────────┘
                          │ TCP 分段
  ┌───────────────────────┴───────────────────────┐
  │ 传输层   TCP 段(20B头 + 数据)                 │  +20B 开销
  └───────────────────────┬───────────────────────┘
                          │ IP 封装
  ┌───────────────────────┴───────────────────────┐
  │ 网络层   IP 包(20B头 + TCP 段)               │  +20B 开销
  └───────────────────────┬───────────────────────┘
                          │ 以太网封装
  ┌───────────────────────┴───────────────────────┐
  │ 链路层   以太网帧(14B头 + IP包 + 4B FCS)      │  +18B 开销
  └───────────────────────┬───────────────────────┘
                          │ 物理编码
  ┌───────────────────────┴───────────────────────┐
  │ 物理层   电信号/光信号                         │  879B 总计
  └───────────────────────────────────────────────┘

2.4. 阶段 4:逐跳转发

markdown 复制代码
路由器收到 IP 包:
  1. 链路层:解封装,取出 IP 包
  2. 网络层:TTL--, 查路由表最长前缀匹配
  3. 若 TTL=0 → 丢包 + ICMP Time Exceeded
  4. 否则:查 ARP 获取下一跳 MAC → 重新封装 → 转发
  5. TCP/TLS/HTTP 层内容不变(只改 IP 和链路层头)
ini 复制代码
  逐跳转发拓扑(IP 端到端不变,MAC 每跳重写,TTL 每跳递减):

  客户端            路由器 R1           路由器 R2           服务器
  10.1.1.2         10.1.1.1/10.3.3.1   10.3.3.2/10.2.2.1   10.2.2.2
    │                  │                   │                   │
    │ 帧[MAC-A→MAC-B]  │                   │                   │
    ├─────────────────▶│ TTL:64→63         │                   │
    │                  │ 帧[MAC-C→MAC-D]   │                   │
    │                  ├──────────────────▶│ TTL:63→62         │
    │                  │                   │ 帧[MAC-E→MAC-F]   │
    │                  │                   ├──────────────────▶│
    │                  │                   │                   │
    └──────────────────┴───────────────────┴───────────────────┘
     IP 头(全程不变):源 10.1.1.2 ──────────────────────▶ 目的 10.2.2.2
     MAC 帧(每跳重写):每段链路只填"本段的下一跳" MAC
     TTL:64 →(R1) 63 →(R2) 62   (减到 0 = 丢弃 + 回 ICMP Time Exceeded)

专家视角 :中间路由器只处理到网络层------它不看 TCP/TLS/HTTP 内容(除非做 DPI)。这是分层架构的效率优势:路由器不需要理解 HTTP 就能转发 HTTP 流量。NAT 是例外------它改 TCP 端口和 IP 地址,触碰了传输层。

2.5. 阶段 5:服务器接收与响应

perl 复制代码
服务器协议栈(自下而上解封装):
  物理层 → 链路层(校验 FCS)→ 网络层(校验 IP 校验和)
  → 传输层(校验 TCP 校验和,查 socket 四元组)
  → TLS 解密 → HTTP 解析 → 路由到应用代码
  → 生成 HTTP 响应 → TLS 加密 → TCP → IP → 链路层 → 发出
markdown 复制代码
  服务器解封装与响应拓扑:

  ┌──────┐    ┌──────┐    ┌──────┐    ┌──────┐    ┌──────┐    ┌──────┐
  │物理层│───▶│链路层│───▶│网络层│───▶│传输层│───▶│TLS   │───▶│HTTP  │
  │      │    │校验FCS│   │校验IP│    │校验TCP│   │解密  │    │解析  │
  │      │    │      │    │路由表│    │socket│   │      │    │路由  │
  └──────┘    └──────┘    └──────┘    └──────┘    └──────┘    └──┬───┘
                                                              │
                                                         应用代码处理
                                                              │
  ┌──────┐    ┌──────┐    ┌──────┐    ┌──────┐    ┌──────┐    └──┬───┘
  │物理层│◀───│链路层│◀───│网络层│◀───│传输层│◀───│TLS   │◀───│HTTP  │
  │      │    │封装帧│    │封装IP│    │封装TCP│   │加密  │    │响应  │
  └──────┘    └──────┘    └──────┘    └──────┘    └──────┘    └──────┘

3. 数据包大小估算

markdown 复制代码
HTTP 请求体(假设 500 字节)
  + HTTP 头部(~300 字节)           = 800 字节
  + TLS Record 头(5 字节)+ AEAD 标签(16 字节) = 821 字节
  + TCP 头部(20 字节,无选项)       = 841 字节
  + IP 头部(20 字节)               = 861 字节
  + 以太网帧头(14 字节)+ FCS(4 字节)= 879 字节
scss 复制代码
  数据包大小逐层累加拓扑:

  应用层  ████████████████████████████████  800B  (HTTP 头+体)
  安全层  █████████████████████████████████  821B  (+21B TLS)
  传输层  ██████████████████████████████████  841B  (+20B TCP)
  网络层  ███████████████████████████████████  861B  (+20B IP)
  链路层  ████████████████████████████████████  879B  (+18B Ethernet)

  协议开销 = 879 - 500 = 379B(75% 开销率)

专家视角 :一个 500 字节的 HTTP 请求,到链路层变成 879 字节------协议开销 75%。这是为什么 HTTP/2 头部压缩(HPACK)和 HTTP/3 多路复用如此重要:减少头部开销和连接数。

4. MTU 与分片

ini 复制代码
以太网 MTU = 1500 字节
  - IP 头 20 - TCP 头 20 = MSS 1460 字节
  - TLS Record 头 5 + 标签 16 = 有效载荷 1439 字节

若应用数据 > 1439 字节 → TLS 分多个 Record
若 TCP 段 > 1460 字节 → 不会分片(MSS 协商保证)
若 IP 包 > 1500 字节 → IP 分片(应避免)
yaml 复制代码
  MTU 分层约束拓扑:

  ┌─────────────────────────────────────────────────────┐
  │  以太网 MTU = 1500 字节                              │
  │  ┌───────────────────────────────────────────────┐  │
  │  │  IP 包 ≤ 1500                                │  │
  │  │  ┌─────────────────────────────────────────┐  │  │
  │  │  │  TCP 段 ≤ 1460(MSS = MTU - IP头 - TCP头)│  │  │
  │  │  │  ┌───────────────────────────────────┐  │  │  │
  │  │  │  │  TLS Record ≤ 1439(MSS - TLS开销) │  │  │  │
  │  │  │  │  ┌─────────────────────────────┐  │  │  │  │
  │  │  │  │  │  HTTP 有效载荷 ≤ 1439        │  │  │  │  │
  │  │  │  │  └─────────────────────────────┘  │  │  │  │
  │  │  │  └───────────────────────────────────┘  │  │  │
  │  │  └─────────────────────────────────────────┘  │  │
  │  └───────────────────────────────────────────────┘  │
  └─────────────────────────────────────────────────────┘

  PPPoE MTU = 1492(-8B PPPoE头)→ MSS 1452 → 需 PMTUD 探测

专家视角 :TCP MSS 钳制 是避免 IP 分片的关键------握手时双方协商 MSS ≤ MTU-40。但跨网络 MTU 可能更小(如 PPPoE 1492),需 PMTUD 探测。PMTUD 黑洞(ICMP 3/4 被防火墙丢弃)是常见性能问题。

5. 完整时序

复制代码
时间    事件                          协议层
0ms     DNS 查询                      DNS/UDP/IP
5ms     DNS 响应                      DNS/UDP/IP
10ms    TCP SYN                       TCP/IP
15ms    TCP SYN-ACK                   TCP/IP
16ms    TCP ACK + TLS ClientHello     TCP/TLS/IP
21ms    TLS ServerHello + 证书        TCP/TLS/IP
22ms    TLS Finished                  TCP/TLS/IP
23ms    HTTP 请求                     HTTP/TLS/TCP/IP
28ms    HTTP 响应                     HTTP/TLS/TCP/IP
30ms    页面渲染开始
vbscript 复制代码
  完整 HTTPS 请求时序拓扑:

  时间   客户端                              服务器
  0ms    ── DNS Query ──────────────────────▶ DNS 服务器
  5ms    ◀── DNS Response ──────────────────
  10ms   ── TCP SYN ────────────────────────▶
  15ms   ◀── TCP SYN+ACK ───────────────────
  16ms   ── TCP ACK + TLS ClientHello ──────▶
  21ms   ◀── TLS ServerHello + 证书 ─────────
  22ms   ── TLS Finished ───────────────────▶
  23ms   ── HTTP 请求 ──────────────────────▶
  28ms   ◀── HTTP 响应 ─────────────────────
  30ms   页面渲染开始

  首次 HTTPS ≈ 30ms(同机房)
  DNS 5ms + TCP 10ms + TLS 10ms + HTTP 5ms

专家视角 :首次 HTTPS 请求约 30ms(同机房),其中 DNS 5ms + TCP 握手 10ms + TLS 握手 10ms + HTTP 往返 5ms。TLS 1.3 0-RTT 可省到 20ms,HTTP/3 连接迁移可省重连开销。

相关推荐
别动我齐刘海1 小时前
简历技术栈全面复习——UDP / TCP / CAN / ZMQ / Protobuf 通信工程
网络·c++·python·tcp/ip·机器学习·udp·github
YumiProxy4 小时前
服务器动态IP导致SSH频繁断连?从保活配置到自动重连的完整排查方案
服务器·tcp/ip·ssh
星恒讯工业路由器6 小时前
车载以太网中的TCP与UDP:诊断、服务通信与网络管理怎么选
网络·tcp/ip·udp
Lsetea7 小时前
OpenSSL报path length constraint exceeded:CA层级与pathlen排查
运维·https·ssl证书·openssl·证书链
傲世仙尊9 小时前
HTTP起步-URL域名解析与协议的本质
网络·网络协议·http
Lsetea9 小时前
OpenSSL s_client退出码为0却证书验证失败:严格校验与Shell管道排查
https·shell·ssl证书·openssl·tls
wdfk_prog11 小时前
Wi-Fi Direct 教程 05:control socket 与 eloop——P2P_FIND 怎样进入 wpa_supplicant 命令解析器
运维·服务器·后端·网络协议·ubuntu·p2p·wifi-direct
Lsetea11 小时前
OpenSSL报permitted subtree violation:证书SAN与CA名称约束排查
运维·https·ssl证书·openssl·证书链
ITxiaobing20231 天前
自研 IP 库与 AppsFlyer 判定不一致的排查实践
网络·网络协议·tcp/ip