Skip to content

一个 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)三条线在一次真实请求里彻底贯通——这正是理解全部网络分层知识的「总钥匙」。