1. 基础概念:分层与数据传递
分层模型与封装
| 五层教学模型 | 核心职责 | 典型例子 |
|---|---|---|
| 应用层 | 定义应用如何交换信息 | HTTP、DNS |
| 传输层 | 在两端的应用之间传输数据 | TCP、UDP |
| 网络层 | 将分组跨网络送向目的地 | IP、路由 |
| 数据链路层 | 在同一条链路上交付帧 | 以太网、Wi-Fi 的链路功能 |
| 物理层 | 通过介质传输比特对应的信号 | 电信号、光信号、无线电波 |
- OSI 七层模型:在应用层与传输层之间,还有表示层、会话层。
- TCP/IP 四层模型:应用层、传输层、网际层、链路层。
表示层处理编码与数据表示,会话层管理会话;TCP/IP 将这些功能并入其他层。
封装:逐层添加控制信息;解封装:接收方反向处理。未加密的 HTTP over TCP 示例:
应用层: HTTP 数据
传输层: TCP 头 + HTTP 数据
网络层: IP 头 + TCP 头 + HTTP 数据
链路层:帧头 + IP 头 + TCP 头 + HTTP 数据 + 帧尾
物理层:将这些比特编码成信号发送同层协议是逻辑上的对等通信,实际数据仍经过下层传输。
LAN、WAN 与接入网
- LAN,局域网:例如家庭、办公室中的网络。
- MAN,城域网:覆盖城市范围的网络。
- WAN,广域网:连接较远地区的网络。
- 接入网:将用户连接到运营商网络的部分。
连上 Wi-Fi 只表示接入无线局域网,不保证能访问互联网。
面向连接与无连接
| 对比 | 面向连接 | 无连接 |
|---|---|---|
| 通信前 | 先建立连接 | 无须先建立连接 |
| 通信状态 | 双方维护连接状态 | 按独立报文处理 |
| 典型例子 | TCP | UDP、IP |
| 顺序与可靠性 | 取决于具体协议;TCP 提供可靠、有序的字节流 | UDP、IP 本身不保证可靠、有序交付 |
TCP 连接是两端维护的序号、窗口和状态。IP 分组可以乱序到达,TCP 整理后按序交给应用。
各层反复处理的五类问题
| 问题 | 直观含义 |
|---|---|
| 寻址 Addressing | 数据从谁来、发给谁 |
| 差错控制 Error Control | 发现损坏、丢失,并按协议进行纠正或重传 |
| 流量控制 Flow Control | 避免发送方把接收方的缓冲区塞满 |
| 复用与分用 | 多个通信共享资源,收到后再正确分给各自的应用 |
| 路由 Routing | 决定通往目的地的路径 |
作用范围不同:链路层处理一段链路,TCP 处理端到端传输。
2. 物理层:把比特变成信号
香农公式:带噪声信道的容量上限
- :理论信道容量,单位是 bit/s。
- :信道带宽,单位是 Hz。
- :信号功率与噪声功率之比,必须使用线性比值。
假设:
那么:
如果题目给的是分贝,需要先转换:
例如 对应 。
容量随频谱带宽线性增长,随信噪比对数增长。实际吞吐量还要扣除编码、协议等开销。
区分单位:频谱带宽用 Hz,数据速率用 bit/s。
有线与无线传输介质
| 介质 | 特点与典型用途 |
|---|---|
| 双绞线 Twisted Pair | 铜线成对绞合,帮助抑制干扰;常见于以太网布线 |
| 同轴电缆 Coaxial Cable | 有中心导体和屏蔽结构;用于有线电视等系统 |
| 光纤 Fiber Optics | 用光传输,容量大、适合长距离、不受电磁干扰 |
| 微波 Microwave | 无线传输;定向链路通常需要考虑视距和遮挡 |
| 红外线 Infrared | 常见于近距离通信,例如遥控器 |
| 通信卫星 | 覆盖范围大;传播时延与轨道高度有关 |
波长与频率的关系是:
是真空光速;在介质中用对应传播速度 。
载波频率(Hz)不等于数据速率(bit/s)。
频分、时分与波分复用
- FDM,频分复用:分配不同频段。
- TDM,时分复用:分配不同时间片。
- WDM,波分复用:同一光纤传输不同波长的光。
3. 数据链路层:成帧与可靠交付
成帧:识别数据的边界
成帧:从比特流中识别每帧的边界。
| 方法 | 原理 | 需要注意的问题 |
|---|---|---|
| 字节计数 | 在帧中记录长度 | 长度字段损坏可能导致边界识别错误 |
| 标志字节+字节填充 | 用特殊字节标记边界,数据中的同类字节需要转义 | 接收方需要撤销转义 |
| 标志比特+比特填充 | 用特殊比特模式标记边界,修改数据中可能冲突的模式 | 接收方需要删除填充比特 |
| 物理层编码违例 | 使用不会出现在正常数据中的特殊编码符号 | 依赖具体物理编码方案 |
比特填充示例:以 01111110 为边界时,数据中每连续五个 1 后插入 0,接收方再删除,避免把数据误认成边界。
滑动窗口:允许多帧同时在途
停等方式:
发送 0 → 等待确认 → 发送 1 → 等待确认 → …停等会浪费等待时间。滑动窗口允许多帧同时在途;窗口为 4 时:
当前允许发送:0、1、2、3
收到对 0 号帧的确认后:
窗口向前移动:1、2、3、4收到确认后,窗口前移,允许发送新数据。
速率为 、往返时延为 RTT 时,充分利用链路所需的在途数据量约为:
这就是带宽时延积。
Go-Back-N 与选择重传
假设发送了:
0、1、2、3、4、5其中 2 号帧出错:
| 行为 | Go-Back-N,回退 N | Selective Repeat,选择重传 |
|---|---|---|
| 接收方收到后续的 3、4、5 | 通常丢弃 | 缓存 |
| 重传时 | 从缺失处重传后续未确认帧 | 只重传缺失或出错帧 |
| 接收方缓存需求 | 较低 | 较高 |
| 实现复杂度 | 较简单 | 较复杂 |
| 丢包后的带宽浪费 | 较大 | 较小 |
选择重传可以乱序接收,但补齐缺口后才按序向上层交付。
4. 网络层:寻址、路由与跨网转发
距离向量:根据邻居的距离更新路由
每个路由器维护“到各个目的地的代价”,并与邻居交换信息。
对每个邻居 ,计算“到邻居的代价 + 邻居到目的地的代价”,取最小值。
J 到 C 的候选路径:
| 经过邻居 | J 到邻居的代价 | 邻居报告的到 C 的代价 | 总代价 |
|---|---|---|---|
| A | 8 | 25 | 33 |
| I | 10 | 18 | 28 |
| H | 12 | 19 | 31 |
| K | 6 | 36 | 42 |
所以 J 更新路由表:
目的地 C:代价 28,下一跳 I代价可表示跳数、时延等。邻居报告过期时,可能出现环路或无穷计数。
链路状态:根据拓扑计算最短路径
发现邻居与链路代价 → 洪泛链路状态 → 根据拓扑运行 Dijkstra。
Seq. 区分信息新旧,Age 帮助淘汰过期信息。
| 距离向量 | 链路状态 |
|---|---|
| 邻居告诉我“它到各处有多远” | 各路由器公布“自己连接谁、代价是多少” |
| 根据邻居的距离更新路由 | 根据拓扑图计算路由 |
| 典型数学基础是 Bellman-Ford | 典型计算方法是 Dijkstra |
隧道:在分组外再加一层封装
IPv6 穿越 IPv4 网络的封装:
进入隧道前: IPv6 分组
经过 IPv4 网络时:IPv4 头 + IPv6 分组
离开隧道后: IPv6 分组中间按外层 IPv4 头转发,出口去掉外层。隧道是否加密取决于具体协议。
IPv4 首部:转发所需的信息
IPv4 首部为 20–60 字节。
| 字段 | 作用 |
|---|---|
| Version | IP 版本,IPv4 中为 4 |
| IHL | 首部长度,以 4 字节为单位;值为 5 表示 20 字节 |
| Total Length | 整个 IPv4 分组的长度,包括首部和数据 |
| Source / Destination Address | 源、目的 IPv4 地址,各 32 位 |
| TTL | 限制分组在网络中继续转发的次数,防止无限循环 |
| Protocol | 指明载荷交给哪种上层协议,例如 TCP 为 6、UDP 为 17 |
| Header Checksum | 检查 IPv4 首部是否损坏 |
| Identification、Flags、Fragment Offset | 支持分片与重组 |
| Differentiated Services | 与服务区分、拥塞通知等有关 |
- Protocol 字段不是端口号:它先决定交给 TCP 还是 UDP;端口再决定交给哪个应用端点。
- IPv4 首部校验和不覆盖数据载荷。
分片:DF 禁止分片,MF 表示还有后续分片,偏移以 8 字节为单位。
IP 地址:从分类地址到 CIDR
早期分类:A/B/C 类默认前缀为 /8、/16、/24;D 类组播,E 类保留。
现在使用 CIDR,以明确的 /n 判断网络前缀。127.0.0.0/8 为回环地址。CIDR
例如:
192.168.8.34/24表示前 24 位是网络前缀,剩余 8 位是主机部分。
子网与路由聚合
先看一个 /24:
主机地址:192.168.8.34/24
子网掩码:255.255.255.0
网络地址:192.168.8.0
广播地址:192.168.8.255普通 /24 广播子网有 256 个地址,通常可分配 254 个主机地址。
网络地址可以通过按位与计算:
路由聚合可以把下面 8 个连续、对齐的 /24 前缀:
192.168.8.0/24
192.168.9.0/24
…
192.168.15.0/24聚合为:
192.168.8.0/218 个网络需要 3 位区分,聚合后的前缀长度为:
第三个字节从 8 到 15:
8 = 00001000
15 = 00001111
└───┘
前 5 位相同共同前缀:16 + 5 = 21 位。
覆盖 192.168.8.0–192.168.15.255。路由聚合不改变原有局域网的边界。
SNAT 与 DNAT
SNAT 示例:
转换前的源:10.0.0.1:5544
转换后的源:198.60.42.12:3344源地址与源端口都发生了转换。
- SNAT:改变源地址,常见于内网主机访问外网。
- DNAT:改变目的地址,常见于将公网入口映射到内部服务器。
例如 DNAT:
外部请求:203.0.113.5:8080
内部目标:10.0.0.10:80设备记录映射,回程执行反向转换;地址与端口转换让多个内网连接共享公网 IP。
ARP、RARP 与 DHCP
ARP:在本地链路上由 IPv4 地址查询 MAC 地址。
外网目标查下一跳网关的 MAC:帧发给网关,IP 分组仍指向远端服务器。
RARP:由硬件地址获取 IP 的历史协议。
DHCP:自动配置 IP、子网掩码、网关和 DNS。首次获取的 DORA 流程:
Discover → Offer → Request → ACK
发现服务器 → 提供配置 → 请求选定配置 → 确认分配地址有租约,到期前需要续租。DHCP
OSPF 与 BGP
AS(自治系统):执行统一路由策略的一组网络,如某运营商的网络。
| 协议 | 主要角色 | 核心思想 |
|---|---|---|
| OSPF | 自治系统内部路由 | 链路状态、最短路径计算、区域划分 |
| BGP | 自治系统之间交换路由 | 路径属性与路由策略 |
BGP 根据 AS 路径等属性和管理策略选路,不保证物理距离最短或时延最低。
5. 传输层:端点、可靠性与发送控制
端口与通信端点
IP 提供网络层地址,端口区分应用通信端点。
一条 TCP 连接通常由四元组区分:
源 IP、源端口、目的 IP、目的端口例如:
192.168.1.10:51000 → 203.0.113.20:443
192.168.1.10:51001 → 203.0.113.20:443源端口不同就是不同连接,服务器的同一个 443 端口可服务多个连接。
UDP:保留报文边界的传输
UDP 首部固定 8 字节,包含四个各 16 位的字段:
| 字段 | 作用 |
|---|---|
| Source Port | 源端口 |
| Destination Port | 目的端口 |
| Length | UDP 首部与数据的总长度 |
| Checksum | 用于差错检测 |
UDP 保留报文边界;丢包重传、排序和发送速率控制由上层按需处理。
常见用途:DNS、实时音视频、QUIC 等。开销小不保证应用一定更快。
常见服务端口
| 端口 | 服务 |
|---|---|
| 21 | FTP 控制连接 |
| 20 | FTP 主动模式中的常见服务器数据端口 |
| 22 | SSH |
| 25 | SMTP |
| 80 | HTTP |
| 110 | POP3 |
| 143 | IMAP |
| 443 | HTTPS |
| 554 | RTSP |
| 631 | IPP 打印协议 |
以上是默认端口,可另行配置。IANA 端口登记
TCP 首部与字节序号
TCP 首部至少 20 字节。
- Sequence Number:本段数据的起始字节序号。
- Acknowledgment Number:接收方接下来期望收到的序号。
- Window:接收方通告的接收窗口。
- Checksum:对 TCP 首部、数据以及伪首部信息进行差错检测。
- Flags:例如 SYN、ACK、FIN、RST。
- Options:例如最大报文段长度、窗口扩大、时间戳等。
TCP 的序号按字节计数。假设发送:
SEQ = 1000
数据长度 = 500 字节数据占用序号 1000–1499,连续收到后确认:
ACK = 1500ACK 是下一个期望的字节序号,不是已收到的最后一个序号。
TCP 没有消息边界:两次 send() 不一定对应两次 recv()。应用需用长度字段、分隔符等划分消息。
TCP 三次握手
三次握手示意。查看大图 · Mermaid 源文件
- 客户端提出建立连接,并公布自己的初始序号。
- 服务器确认客户端的序号,同时公布自己的初始序号。
- 客户端确认服务器的序号。
第三次握手确认客户端已收到服务器的初始序号,也避免旧连接请求直接建立错误连接。
SYN 会占用一个序号,所以图中的确认号需要加 1。
TCP 关闭与半关闭
客户端 → 服务器:FIN,我没有更多数据要发送
服务器 → 客户端:ACK,确认你的发送方向结束
服务器仍可发送剩余数据……
服务器 → 客户端:FIN,我也没有更多数据要发送
客户端 → 服务器:ACK,确认你的发送方向结束半关闭:发出 FIN 后,仍可接收对端数据。
ACK 与 FIN 可以合并;FIN 和 SYN 都占用一个序号。
TCP 状态机
主动建立:
CLOSED → SYN-SENT → ESTABLISHED
被动建立:
LISTEN → SYN-RECEIVED → ESTABLISHED
典型主动关闭:
ESTABLISHED → FIN-WAIT-1 → FIN-WAIT-2 → TIME-WAIT → CLOSED
典型被动关闭:
ESTABLISHED → CLOSE-WAIT → LAST-ACK → CLOSED- CLOSE-WAIT:已收到对方 FIN,等待本地应用关闭发送方向;长期停留需检查应用是否及时关闭连接。
- TIME-WAIT:保留状态以确认重传的 FIN,并避免旧报文干扰后续连接。
TIME-WAIT 通常等待 2MSL,MSL 是最大报文生存时间,不是 RTT。TCP 关闭
流量控制与拥塞控制
| 窗口 | 解决的问题 | 谁决定 |
|---|---|---|
接收窗口 rwnd | 接收方还能接收多少数据 | 接收方通告 |
拥塞窗口 cwnd | 网络目前适合承载多少未确认数据 | 发送方根据反馈调整 |
未确认数据量主要受以下上限约束:
可发的新数据量还要扣除在途数据。TCP 首部 Window 通告 rwnd,cwnd 由发送方维护。
| 阶段 | 窗口变化的直观规律 |
|---|---|
| 慢启动 | 从较小窗口开始,在理想条件下约每个 RTT 翻倍 |
| 拥塞避免 | 达到阈值后,改为大致线性增长 |
| 超时重传 | 大幅降低窗口,重新慢启动 |
| 快速重传、快速恢复 | 利用重复 ACK 尽早发现疑似丢包,并降低发送强度 |
窗口增长示意:
慢启动: 1 → 2 → 4 → 8
拥塞避免: 8 → 9 → 10 → 11初始值 1 仅用于示意。
经典快速重传以 3 个重复 ACK 判断疑似丢包,在超时前重传;快速恢复降低窗口,但避免每次重回慢启动。TCP 拥塞控制
6. 应用层:DNS 与 HTTP
DNS 名字空间
以这个域名为例:
robot.cs.washington.edu.从右向左看:
. 根
edu 顶级域
washington 下一级域
cs 再下一级域
robot 具体名称末尾的点表示根,通常省略;各级域可分别管理。
URL 中只有主机名参与名字解析:
https://www.example.com/course?id=19
└── 域名 ────┘└─ 路径与查询 ─┘DNS 资源记录
| 类型 | 作用 |
|---|---|
| A | 名称对应的 IPv4 地址 |
| AAAA | 名称对应的 IPv6 地址 |
| CNAME | 名称的别名,指向另一个名称 |
| MX | 接收邮件的服务器及优先级 |
| NS | 某个区域的权威名称服务器 |
| SOA | 区域的管理信息,例如序列号、刷新参数 |
| PTR | 反向解析中使用的名称指针 |
| TXT | 文本信息,常用于验证、邮件策略等 |
| SRV | 服务位置,包括目标、端口、优先级等 |
SPF 策略放在 TXT 记录中。SPF
DNS 查询与缓存
假设缓存没有结果,要解析 robot.cs.washington.edu:
- 计算机向配置的递归解析器提出查询。
- 解析器询问根服务器,获得
.edu的服务器线索。 - 询问
.edu服务器,获得washington.edu的服务器线索。 - 继续沿委派关系查询,例如找到负责
cs.washington.edu的服务器。 - 获得结果后返回给客户端,并按规则缓存。
- 客户端要求递归解析器帮自己得到结果。
- 解析器向其他服务器逐步查询的过程通常是迭代查询。
根服务器通常只返回下一步该问谁。
DNS TTL 是缓存有效时间;IP TTL 限制转发次数。命中缓存时,不必从根重新查询。
HTTP 连接复用
| 方式 | 工作过程 | 主要问题或收益 |
|---|---|---|
| 每次使用新连接 | 建连 → 请求 → 响应,之后重新建连 | 重复承担建连成本 |
| 持久连接、顺序请求 | 保留连接,一个响应完成后再发下一个请求 | 节省建连成本,但请求仍串行 |
| 持久连接、流水线请求 | 不等前一个响应就发送后续请求 | 减少请求等待,但响应顺序仍受约束 |
- HTTP/1.1 流水线:提前发送后续请求,响应仍按序返回。
- HTTP/2:多个流的帧交错传输;TCP 丢失字节会阻塞其上的多个流。
- HTTP/3:基于 UDP 上的 QUIC,减少跨流的传输层队头阻塞。版本差异
HTTP 方法与状态码
| 方法 | 含义 |
|---|---|
| GET | 获取资源的表示 |
| HEAD | 获取类似 GET 的响应元信息,但不返回响应内容 |
| POST | 将数据交给目标资源,按其语义处理 |
| PUT | 用请求中的表示创建或替换目标资源状态 |
| DELETE | 请求删除目标资源与当前功能的关联 |
| OPTIONS | 查询通信选项 |
| CONNECT | 建立隧道,常用于代理场景 |
| TRACE | 请求诊断性的回送信息 |
幂等性:重复请求的预期效果与执行一次相同,例如 PUT 同一份内容;不要求响应状态码相同。HTTP 方法
| 范围 | 含义 | 示例 |
|---|---|---|
| 1xx | 中间信息 | 100 Continue |
| 2xx | 成功 | 200 OK、201 Created、204 No Content |
| 3xx | 重定向或条件请求相关结果 | 301、302、304 |
| 4xx | 请求存在客户端相关问题 | 400、401、403、404 |
| 5xx | 服务器处理失败 | 500、502、503、504 |
401:缺少有效的认证凭据。403:服务器理解请求,但拒绝执行。404:没有找到请求的资源。304:条件请求下资源未修改,可以继续使用已有缓存;它不是普通的跳转响应。204:请求成功,但没有响应内容。
HTTP 首部与缓存验证
| 用途 | 典型字段 |
|---|---|
| 请求目标与客户端信息 | Host、User-Agent、Referer |
| 内容协商 | Accept、Accept-Encoding、Accept-Language |
| 身份与状态 | Authorization、Cookie、Set-Cookie |
| 内容描述 | Content-Type、Content-Length、Content-Encoding |
| 缓存与条件请求 | Cache-Control、ETag、If-None-Match、Last-Modified、If-Modified-Since |
| 跳转和范围请求 | Location、Range、Content-Range、Accept-Ranges |
Accept:“我可以接收哪些类型”;Content-Type:“这份内容是什么类型”。Accept-Encoding:“我支持哪些内容编码”;Content-Encoding:“这份内容实际使用什么编码”,例如 gzip。Set-Cookie:服务器要求客户端保存 Cookie;Cookie:客户端按规则在后续请求中携带。ETag:服务器给出的表示版本标识;If-None-Match:客户端拿已有标识进行条件查询。
请求也可以包含 Content-Type、Content-Length。
HTTP/1.1 条件请求示例:
GET /index.html HTTP/1.1
Host: example.com
Accept: text/html
Accept-Encoding: gzip
If-None-Match: "v3"
空行结束首部。
资源仍匹配 "v3" 时:
HTTP/1.1 304 Not Modified
ETag: "v3"
Cache-Control: max-age=60
- 缓存仍新鲜:直接使用,可不发请求。
- 需要验证且资源未修改:请求后收到 304,复用缓存内容,省去资源正文传输。
补充案例:用一次商品页访问串起各层
条件:以太网接入,IPv4,无可用缓存或已有连接;DNS 使用 UDP,网站使用 HTTP/2 + TLS 1.3 + TCP。地址和端口映射均为示例。
访问商品页:
https://shop.example.com/products/42?color=blue#reviews| 角色 | 地址 |
|---|---|
| 电脑 | 192.168.1.10/24 |
| 默认网关,路由器 LAN 接口 | 192.168.1.1 |
| 路由器 WAN 接口 | 198.51.100.23 |
| DNS 递归解析器 | 192.0.2.53 |
| 网站服务器,稍后由 DNS 查到 | 203.0.113.80 |
入网配置与 URL 解析
DHCP 预先解决四个配置问题:
我自己的 IP 是多少?
哪些地址和我在同一个子网?
访问外网应该交给谁?
应该找谁查询 DNS?本例由家用路由器提供 DHCP 服务,客户端使用 UDP 68,服务器使用 UDP 67:
电脑 DHCP 服务器
│── DHCP Discover ────────────→│
│←─ DHCP Offer ────────────────│
│── DHCP Request ─────────────→│
│←─ DHCP ACK ──────────────────│DHCP 配置如下;只在获取或更新租约时执行。
IP 地址: 192.168.1.10
子网掩码: 255.255.255.0
默认网关: 192.168.1.1
DNS 服务器: 192.0.2.53浏览器再解析 URL:
| 部分 | 值 | 用途 |
|---|---|---|
| Scheme | https | 使用 HTTPS |
| Host | shop.example.com | 主机名 |
| Port | 默认 443 | 服务端口 |
| Path | /products/42 | 资源路径 |
| Query | color=blue | 查询参数 |
| Fragment | reviews | 页面内定位 |
我要通过 HTTPS,
访问 shop.example.com 的 443 端口,
请求 /products/42?color=blue。#reviews 由浏览器定位,不随 URL 发给服务器。
DNS 请求发出前,先解决路由与 ARP
需要查询的问题是:
shop.example.com 的 IPv4 地址是什么?这次查询使用的端点是:
源:192.168.1.10:53000
目的:192.0.2.53:53
传输协议:UDP本地子网与选中的路由分别是:
192.168.1.0/24默认路由 → 下一跳 192.168.1.1DNS 服务器在外网;无网关 ARP 缓存时,先广播:
谁的 IP 是 192.168.1.1?
请告诉 192.168.1.10 你的 MAC 地址。路由器回复,电脑记录映射:
192.168.1.1 是我,
我的 MAC 地址是 02:00:00:00:00:01。192.168.1.1 → 02:00:00:00:00:01两层的目的地址因此不同:
IP 目的地址: DNS 服务器的 IP
帧目的 MAC: 网关的 MACARP 无 TCP/UDP 端口,只查询下一跳 MAC;因此这里先 ARP,再发送 DNS 查询。
DNS 查询的封装与解析
请求逐层加上首部,最终编码为信号:
应用层
DNS 查询:shop.example.com 的 A 记录是什么?
↓ 加 UDP 首部
传输层
UDP:源端口 53000,目的端口 53
↓ 加 IPv4 首部
网络层
IPv4:源 192.168.1.10,目的 192.0.2.53
↓ 加以太网首部、帧尾
数据链路层
以太网:源 MAC 是电脑,目的 MAC 是网关
↓ 编码、调制为信号
物理层
通过网线发送电信号路由器转发 IP 分组并建立 UDP NAT 映射。解析器无缓存时逐级查询:
电脑
│
│ shop.example.com 的地址是什么?
↓
递归解析器
│
├─ 问根服务器
│ → 获得 .com 名称服务器的线索
│
├─ 问 .com 名称服务器
│ → 获得 example.com 权威服务器的线索
│
└─ 问 example.com 权威服务器
→ shop.example.com 的 A 记录是 203.0.113.80解析结果与网站服务端点是:
shop.example.com → 203.0.113.80目标服务:203.0.113.80:443解析器使用自己的端点查询各级服务器,结果按 DNS TTL 缓存。
TCP 连接经过 NAT 与逐跳转发
电脑选择临时 TCP 端口 51514:
192.168.1.10:51514 → 203.0.113.80:443路由器将它映射到公网端点,服务器看到转换后的源:
TCP 连接的内部端点 对外使用的端点
192.168.1.10:51514 ↔ 198.51.100.23:62001198.51.100.23:62001分组沿途经过:
电脑 → 家用路由器 → 运营商网络 → 其他网络 → 网站所在网络 → 服务器路由器查转发表、递减 TTL、重新封装出链路帧;普通二层交换机转发时通常不改源、目的 MAC。
具体访问中的三次握手,每条箭头都经过底层网络。查看大图 · Mermaid 源文件
TCP 提供可靠字节流;身份验证和加密由 TLS 完成。
TLS 握手:验证身份与派生密钥
TLS 1.3 完整证书握手:
浏览器 服务器
│── ClientHello ───────────────────────────→│
│ 支持的版本、算法、临时密钥交换信息等 │
│ │
│←─ ServerHello ────────────────────────────│
│←─ 加密扩展、证书、签名证明、Finished ───────│
│ │
│ 验证证书与握手消息 │
│── Finished ──────────────────────────────→│
│ │
│←──────── 加密的应用数据 ──────────────────→│- 验证:证书域名、信任链、有效期和签名证明。
- 密钥:临时密钥交换派生通信密钥,后续数据使用对称加密与完整性保护。
SNI 表明目标服务器名称;ALPN 协商应用协议,本例选择 h2,即 HTTP/2。TLS 1.3 握手
HTTP 请求、服务器处理与响应
HTTP/2 初始化后,请求字段如下;线上编码为二进制帧:
:method: GET
:scheme: https
:authority: shop.example.com
:path: /products/42?color=blue
accept: text/html
accept-encoding: gzip, br请求的应用含义是:
请给我 42 号商品的蓝色版本页面。
我希望收到 HTML,也支持相应的内容压缩。请求封装与以太网帧结构:
HTTP/2:把请求编码成 HEADERS 等帧
↓
TLS:加密、添加完整性保护
↓
TCP:把字节流组织成报文段
↓
IP:添加源、目的 IP 等网络层信息
↓
以太网:封装成发往网关的帧
↓
物理层:通过信号发送[以太网头][IPv4 头][TCP 头][TLS 字节流的一部分][FCS]各层边界不必对齐。HTTP/2 帧与流 服务器反向处理:
物理层恢复信号中的比特
↓
网卡与链路层识别帧、检查 FCS
↓
IP 层处理发给本机的分组
↓
TCP 根据连接信息接收、排序、去重,交付连续字节
↓
TLS 验证并解密
↓
HTTP/2 解析请求
↓
网站应用处理 /products/42?color=blue查找商品 42
→ 选择蓝色款式
→ 读取名称、价格和图片地址
→ 生成 HTML应用生成 HTML:
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="/assets/site.css">
<script defer src="/assets/product.js"></script>
</head>
<body>
<h1>蓝色机械键盘</h1>
<p class="price">¥299</p>
<img src="/images/keyboard-blue.webp"
width="600" height="400" alt="蓝色机械键盘">
<section id="reviews">用户评论</section>
</body>
</html>响应字段可能是:
:status: 200
content-type: text/html; charset=utf-8
content-encoding: br压缩后的内容经 TLS、TCP/IP 返回。本例将 HTTPS 入口和应用合并,实际还可能有 CDN 或反向代理。
响应回程、丢包与资源复用
响应在公网中,以及经过反向 NAT 后的端点分别是:
203.0.113.80:443 → 198.51.100.23:62001203.0.113.80:443 → 192.168.1.10:51514如果第二段丢失:
发送顺序:第 1 段、第 2 段、第 3 段、第 4 段
实际收到:第 1 段、 第 3 段、第 4 段TCP 缓存后续数据,重传补齐后按序交付。发送量受两类限制:
接收方有没有空间? → 流量控制、接收窗口
网络能否承受? → 拥塞控制、拥塞窗口TCP 确认不等于页面已显示。浏览器解密、解压、解析后发现依赖:
<link rel="stylesheet" href="/assets/site.css">
<script defer src="/assets/product.js"></script>
<img src="/images/keyboard-blue.webp">依赖资源可复用同一条 HTTP/2 连接:
GET /assets/site.css
GET /assets/product.js
GET /images/keyboard-blue.webp同一条 TCP/TLS 连接中:
CSS 数据 → 图片数据 → JS 数据 → 图片数据 → CSS 数据……不同流的帧可以交错传输,但 TCP 字节流的缺口仍可能让多个流等待。
浏览器渲染与后续请求
HTML 生成 DOM,CSS 参与样式计算,随后才能确定布局并绘制:
浏览器渲染的主要依赖关系。查看大图 · Mermaid 源文件
DOM 表示文档结构;布局算位置与尺寸,绘制生成指令,栅格化与合成生成并组合像素。下载与渲染可交错进行。浏览器渲染
defer 下载不阻塞 HTML 解析;图片宽高预留空间;评论区可用后处理 #reviews。
页面显示后,脚本还可能查询库存:
fetch("/api/stock?product=42")
.then(response => response.json())
.then(data => {
// 根据库存结果更新页面
});这个请求再次经过各层,并可能触发页面更新:
HTTP 请求
→ TLS
→ TCP
→ IP
→ 链路层
→ 物理层
→ 服务器
→ 响应返回
→ JavaScript 更新 DOM
→ 必要的样式、布局、绘制更新首次显示、DOMContentLoaded、load、业务数据就绪是不同时间点;连接可继续复用。
完整时序图:一起跟踪 IP、MAC 与端口
MAC 使用下表代号;互联网折叠多个路由跳点。TLS、HTTP 的端到端箭头仍经过相同路径。
| MAC 代号 | 对应接口 |
|---|---|
C | 电脑网卡 |
GL / GW | 家用路由器的 LAN / WAN 接口 |
I | 运营商第一跳路由器接口 |
RD / RS | DNS / 网站链路的最后一跳路由器接口 |
D / S | DNS / 网站服务器网卡 |
完整时序图,建议打开大图查看地址细节。查看大图 · Mermaid 源文件
| 字段 | 电脑发出 | NAT 后进入公网 | 普通路由转发 | 返回家庭网络 |
|---|---|---|---|---|
| IP | 源为电脑内网 IP | 源改为路由器公网 IP | 地址通常保持,TTL 递减 | 目的改回电脑内网 IP |
| TCP 端口 | 源端口 51514 | 源端口改为 62001 | 保持不变 | 目的端口改回 51514 |
| MAC | C → GL | GW → I | 每个路由跳点重新封装 | 最后一跳 GL → C |
UDP 映射 53000 ↔ 63000,TCP 映射 51514 ↔ 62001,两者独立。