一个 HTTP 请求穿越协议栈的端到端旅程
基于 HTTP 现代标准 · 核于 2026-06
速查
- 总览顺序:地址栏输入
https://example.com回车 → ① DNS 解析(域名→IP)→ ② TCP 三次握手(建连)→ ③ TLS 握手(协商加密)→ ④ HTTP 请求/响应 → 浏览器渲染。前三步都是「正式说话前的铺垫」,第四步才真正传业务数据。 - DNS 解析(应用层):把
example.com解析成 IP(如93.184.216.34),底层走 UDP/53。这一步本身又是一次完整的协议栈穿越,详见 DNS 解析全过程。 - TCP 握手(传输层):
SYN → SYN+ACK → ACK建立可靠连接,耗 1 个 RTT。详见 TCP 三次握手。 - TLS 握手(表示/会话层概念,实务在 TCP 之上):验证证书、协商对称密钥,TLS 1.3 仅需 1-RTT。详见 TLS 握手。
- 自顶向下封装(发送方):HTTP 报文 →(加 TCP 头)TCP 段 →(加 IP 头)IP 包 →(加帧头+帧尾)以太网帧 → 物理层比特流。每下一层加一层「信封」。
- 交换机(链路层):只看目的 MAC做局域网内转发,不拆 IP 头、不改地址,是「二层设备」。
- 路由器(网络层):逐跳转发,每过一跳重写源/目的 MAC(指向下一跳),但始终不改源/目的 IP,是「三层设备」。
- 「MAC 逐跳变、IP 端到端不变」:本章最该记牢的一句。MAC 解决「下一跳给谁」,IP 解决「最终去哪」。
- 自底向上解封装(接收方):比特 → 帧(剥帧头校验 MAC)→ IP 包(剥 IP 头校验目的 IP)→ TCP 段(剥 TCP 头、按端口交给进程)→ HTTP 报文,逐层「拆信封」。
- 响应原路返回:服务器的 HTTP 响应同样自顶向下封装、穿越路由器、被浏览器自底向上解封装,最终交给渲染引擎。
- 一句话:分层(OSI/TCP-IP)规定了「谁负责什么」,封装/解封装规定了「数据怎么打包传输」,本页把二者用一次真实请求串成完整闭环。
一、舞台搭建:回车之后发生了什么
在地址栏输入 https://example.com 按下回车,浏览器并不能立刻发出 HTTP 请求——它得先解决三个前置问题:「对方 IP 是多少」「连接通不通」「通道安不安全」。MDN 在《How browsers work》中明确给出了这一固定次序:
DNS lookup → TCP handshake → TLS negotiation (HTTPS) → HTTP request → response。 —— MDN, How browsers work
浏览器 服务器
│ │
│ ① DNS 解析 example.com ─────────► 93.184.216.34 │ 应用层(UDP/53)
│ ② TCP 握手 SYN → SYN+ACK → ACK │ 传输层(1 RTT)
│ ③ TLS 握手 ClientHello → ... → 协商出对称密钥 │ TLS 1.3:1 RTT
│ ④ HTTP 请求 GET / HTTP/1.1(加密承载)───────────────► │ 应用层
│ ◄─────────────── 200 OK + HTML │
│ ⑤ 渲染 解析 HTML/CSS/JS,构建并绘制页面 │前三步是「铺垫」,第四步才是「正事」
DNS、TCP、TLS 解决的都是「正式对话前的准备」:知道往哪发、建好可靠连接、谈妥加密。真正承载业务的是第④步的 HTTP 报文。理解这一点,就抓住了整条旅程的主线。
① DNS 解析:域名换 IP(应用层)
浏览器先查 example.com 对应的 IP。这一步通常走 UDP/53,命中各级缓存(浏览器→操作系统→本地 DNS→根/顶级/权威)即返回。DNS 查询本身也是一次完整的协议栈穿越(DNS 报文 → UDP 段 → IP 包 → 帧),只是为避免重复,细节归 DNS 解析全过程。
② TCP 三次握手:建立可靠连接(传输层)
拿到 IP,浏览器与服务器的 443 端口做 SYN → SYN+ACK → ACK,双向同步初始序列号、确认收发通道都通,耗约 1 个 RTT。握手成功才有一条可靠的字节流通道。机制细节见 TCP 三次握手。
③ TLS 握手:协商加密(保密与身份)
https 多了一道 TLS 握手:浏览器验证服务器证书(确认对方真是 example.com),并协商出一把对称密钥用于后续加密。TLS 1.3 把握手压到 1-RTT。此后所有 HTTP 报文都在这条加密通道里传输。细节见 TLS 握手。
④ HTTP 请求/响应:传输业务数据(应用层)
通道就绪,浏览器才发出真正的请求报文:
GET / HTTP/1.1
Host: example.com
User-Agent: ...
Accept: text/html服务器回 200 OK 与 HTML 正文。浏览器收到后进入解析与渲染阶段(构建 DOM/CSSOM、布局、绘制)——渲染不属本章网络范畴,到此打住。
二、发送方:自顶向下层层封装
第④步那行 GET / HTTP/1.1 要发出去,必须沿协议栈从上往下逐层打包。维基百科对封装(encapsulation)的定义是「每一层把本层的头部/尾部拼接到上层数据上」——形象地说,每下一层就套一个信封:
应用层 ┌─────────────────────────── HTTP 报文(GET / HTTP/1.1 ...)
│
传输层 ┌──────────┬──────────────────────────────────┐
│ TCP 头 │ HTTP 报文 │ ← 段 Segment(含源/目的端口)
└──────────┴──────────────────────────────────┘
网络层 ┌────────┬──────────┬──────────────────────────┐
│ IP 头 │ TCP 头 │ HTTP 报文 │ ← 包 Packet(含源/目的 IP)
└────────┴──────────┴──────────────────────────┘
链路层 ┌───────┬────────┬────────┬───────────────┬───────┐
│ 帧头 │ IP 头 │ TCP 头 │ HTTP 报文 │ 帧尾 │ ← 帧 Frame(含源/目的 MAC + FCS 校验)
└───────┴────────┴────────┴───────────────┴───────┘
物理层 1010110010110... ──────────────────────────────► ← 比特流(电/光/电磁波)| 层 | 加什么头 | 产物(PDU) | 关键字段 |
|---|---|---|---|
| 应用层 | —(生成数据本身) | HTTP 报文(Message) | 方法、URL、首部 |
| 传输层 | TCP 头 | 段(Segment) | 源/目的端口、序列号 |
| 网络层 | IP 头 | 包(Packet) | 源/目的 IP、TTL |
| 链路层 | 帧头 + 帧尾 | 帧(Frame) | 源/目的 MAC、FCS |
| 物理层 | —(编码为信号) | 比特(Bit) | 电平/光/电磁波 |
每层只认自己那层的「地址」
端口(传输层)告诉接收方「交给哪个进程」,IP(网络层)告诉网络「最终送到哪台主机」,MAC(链路层)告诉本段链路「下一跳交给哪块网卡」。三种地址各司其职,正是分层思想的直接体现,详见 两模型对照与协议归层。
三、网络中途:交换机与路由器各做什么
封装好的帧从网卡发出,要穿过一连串中间设备才能到达服务器。两类设备最关键,工作在不同层次:
浏览器主机 ──帧──► [交换机] ──帧──► [路由器R1] ══包══► [路由器R2] ──帧──► [交换机] ──帧──► 服务器
链路层转发 网络层逐跳转发 网络层逐跳转发 链路层转发
(看目的MAC) (改MAC·不改IP) (改MAC·不改IP) (看目的MAC)交换机:链路层(二层)转发
交换机只看帧头里的目的 MAC,依据 MAC 地址表在局域网内部把帧转给对应端口。它不拆 IP 头、不改任何地址,只在同一个局域网(同一网段)内搬运帧。
路由器:网络层(三层)逐跳转发
跨网段就得靠路由器。路由器拆开帧、读 IP 头,按路由表决定「下一跳」该走哪个出口,然后重新封装一个新帧再发出去。这里藏着本章最核心的一条规律:
MAC 逐跳变,IP 端到端不变
- 目的 IP / 源 IP:在整段旅程中始终不变(除非有 NAT)——它标识「最终的发送方与接收方」,是端到端的。
- 目的 MAC / 源 MAC:每经过一个路由器就被重写一次——它只标识「这一段链路的上一跳与下一跳」,是**逐跳(hop-by-hop)**的。
一句话:IP 管「最终去哪」,MAC 管「下一跳给谁」。 每过一跳,TTL 还会减 1,归零即丢弃以防环路。这正是 OSI 七层 里网络层与链路层分工的真实写照。
四、接收方:自底向上层层解封装
帧到达服务器网卡,过程完全反过来——维基百科称之为解封装(de-encapsulation):每一层剥掉本层头部、校验无误后把载荷交给上一层。
物理层 1010110010110... ► 收到比特流,还原成帧
链路层 剥【帧头/帧尾】,校验 FCS、核对目的 MAC ► 交给网络层
网络层 剥【IP 头】,核对目的 IP、TTL ► 交给传输层
传输层 剥【TCP 头】,按【目的端口】找到对应进程 ► 交给应用层
应用层 还原出完整 HTTP 报文:GET / HTTP/1.1 ... ► 交给 Web 服务器处理- 链路层:校验帧尾 FCS(坏帧丢弃),确认目的 MAC 是自己,剥头上交。
- 网络层:确认目的 IP 是本机,剥 IP 头,按协议号(这里是 TCP)上交。
- 传输层:剥 TCP 头,按目的端口(443)把数据交给对应的服务进程,并通过序列号/ACK 保证可靠有序。
- 应用层:拼回完整 HTTP 请求,Web 服务器据此生成响应。
封装与解封装是严格的镜像
发送方加的每一层头,都由接收方对应层精确剥掉——HTTP↔HTTP、TCP↔TCP、IP↔IP、帧↔帧。这种「同层对话、逐层封装」正是 TCP/IP 分层模型 能让异构网络互通的根本原因。
五、响应原路返回:闭环
服务器处理完,把 200 OK 与 HTML 作为 HTTP 响应,重复一遍同样的旅程:在服务器侧自顶向下封装(HTTP→TCP→IP→帧→比特),经由路由器逐跳转发(同样改 MAC 不改 IP)穿回公网,到达浏览器后自底向上解封装,最终把 HTML 交给渲染引擎。一来一回,一次完整的请求-响应闭环就此完成。
请求:浏览器 ──封装──► 路由器逐跳 ──► 服务器解封装 ──► 处理
响应:服务器 ──封装──► 路由器逐跳 ──► 浏览器解封装 ──► 渲染呈现小结
本页用「在地址栏输入 https://example.com」这一个真实场景,把整章串成闭环:浏览器先经 ① DNS 解析拿到 IP、② TCP 三次握手建好可靠连接、③ TLS 握手协商加密,才发出 ④ HTTP 请求。发送方将 HTTP 报文自顶向下封装为 TCP 段→IP 包→以太网帧→比特流,每层套一个信封;数据在网络中先后经过只看 MAC 的交换机(链路层转发)和读 IP 头的路由器(网络层逐跳转发)——牢记**「MAC 逐跳重写、IP 端到端不变」这条主线。到达接收方后自底向上解封装**,逐层剥头并按端口交给进程,还原出完整 HTTP 报文;响应再原路封装、转发、解封装返回浏览器渲染。至此,分层(谁负责什么)、封装/解封装(数据怎么打包)、各层协议(DNS/TCP/IP/以太网/HTTP)三条线在一次真实请求里彻底贯通——这正是理解全部网络分层知识的「总钥匙」。
- 上一页:两模型对照与协议归层
- 参考资料:参考