1. http
1.1 浏览器访问一个网页的过程
用户输入网址(域名)
浏览器通过DNS服务器查询域名对应的IP地址(浏览器会将查询结果“域名→IP”缓存在本地)
浏览器与<Web服务器IP地址:80端口>建立TCP连接
浏览器在握手③中携带HTTP请求报文(指明要访问哪个html网页)
服务器返回HTTP响应报文(携带html文件)
如果html引用了其他n个元素,还需要n组HTTP请求&响应(持续、非持续工作方式有所区别)
1.2 http的五种工作方式
——————————————————————————–
1. 非持续连接 (HTTP/1.0)
特点: 一请求一连接,每次都要握手挥手
RTT : 2N (N=资源数量)
——————————————————————————–
客户端 服务器
| |
|— [SYN] ———————–> | (1. TCP握手)
|<– [SYN+ACK] ——————– |
|— [ACK] ———————–> |
| |
|— [REQ 1] ——————— >| (2. 传输对象1)
|<– [RES 1] ———————- |
| |
|— [FIN] ———————–> | (3. TCP挥手 – 关闭)
|<– [ACK+FIN] – – – – – – – – – – -|
| |
|— [SYN] ———————–> | (4. 重新握手 – 传输对象2)
|<– [SYN+ACK] ——————– |
|— [ACK] ———————–> |
|— [REQ 2] ——————— >|
|<– [RES 2] ———————- |
| |
| (每个对象都重复上述过程,效率极低) |
| |
——————————————————————————–
2. 持续连接 – 非流水线 (HTTP/1.1 默认)
特点: 一连接多请求,但必须"等一个回一个" (串行)
RTT : 2 + N
——————————————————————————–
客户端 服务器
| |
|=== TCP 三次握手 (仅1次) ==========>|
| |
|— [REQ 1] ——————— >|
|<– [RES 1] ———————- | (必须等RES1回来)
| |
|— [REQ 2] ——————— >| (才能发REQ2)
|<– [RES 2] ———————- |
| |
|— [REQ 3] ——————— >|
|<– [RES 3] ———————- |
| |
|=== TCP 四次挥手 (最后1次) ========>|
| |
(存在队头阻塞:前一个慢,后面全等)
——————————————————————————–
3. 持续连接 – 流水线 (HTTP/1.1 可选)
特点: 请求可连续发,但响应必须按序回
RTT : 2 (理论最优,但有缺陷)
——————————————————————————–
客户端 服务器
| |
|=== TCP 三次握手 (仅1次) ==========>|
| |
|— [REQ 1] ——————— >|
|— [REQ 2] ——————— >| (不用等,连续发)
|— [REQ 3] ——————— >|
| |
|<– [RES 1] ———————- | (必须按序返回)
|<– [RES 2] ———————- | (若RES1慢,RES2/3做好了也得等)
|<– [RES 3] ———————- |
| |
|=== TCP 四次挥手 ==================>|
| |
(存在响应队头阻塞:浏览器默认禁用)
——————————————————————————–
4. HTTP/2 多路复用 (基于 TCP)
特点: 二进制分帧,多流交错,应用层无阻塞
RTT : 2 (但受限于TCP底层丢包阻塞)
——————————————————————————–
客户端 服务器
| |
|=== TCP 三次握手 + TLS 握手 =======>|
| |
|— [STR 1: HEADERS] ———— >| \\
|— [STR 2: HEADERS] ———— >| } 请求乱序发送
|— [STR 3: DATA ] ————>| /
| |
|<– [STR 2: DATA ] ————-| \\
|<– [STR 1: DATA ] ————-| } 响应乱序返回 (靠流ID重组为一个完整消息)
|<– [STR 3: DATA ] ————-| /
| (帧交错传输,互不等待) |
| |
|=== TCP 四次挥手 ==================>|
| |
(应用层无阻塞。但若TCP包丢失,所有流都会因TCP重传而阻塞)
——————————————————————————–
5. HTTP/3 (基于 QUIC/UDP)
特点: UDP传输,0-RTT握手,彻底解决传输层阻塞
RTT : 0-1 (最快)
——————————————————————————–
客户端 服务器
| |
|— [ClientHello + REQ 1] ——->| (0-RTT: 握手带数据一起发)
|<– [ServerHello + RES 1] ——–|
| |
|— [STR 1: DATA ] ————–>|
|— [STR 2: DATA ] ————–>| 真正的独立并行
| |
|<– [STR 2: DATA ] —————|
|<– [STR 1: DATA ] —————| 某流丢包不影响其他流
| (QUIC协议层独立重传) |
| |
| (连接迁移: IP变了也不用重新握手) |
| |
(彻底解决应用层 + 传输层队头阻塞)
|
核心机制 |
一请求一连接,用完即毁 |
一连接多请求 |
一连接多请求 |
一连接多流 |
一连接多流 |
|
传输层协议 |
TCP |
TCP |
TCP |
TCP |
QUIC (UDP) |
|
数据格式 |
纯文本 |
纯文本 |
纯文本 |
二进制分帧 |
二进制分帧 |
|
TCP连接数 |
N 条 |
1 条 |
1 条 |
1 条 |
1 条 |
|
逻辑流数量 |
1 流/连接 |
1 流/连接 |
1 流/连接 |
多流/连接 |
多流/连接 |
|
队头阻塞 |
无 |
严重:请求层阻塞,前一个没回,后一个不发 |
中等:响应层阻塞,前一个没回完,后一个不回 |
部分解决: |
彻底解决:应用层 + 传输层均无阻塞,丢包只影响当前流 |
|
头部压缩 |
无 |
无 |
无 |
HPACK 消除重复头部 |
QPACK 解决HPACK依赖顺序问题 |
|
连接迁移 |
不支持 |
不支持 |
不支持 |
不支持 |
支持 |
|
加密要求 |
可选 (通常明文) |
可选 (通常明文) |
可选 (通常明文) |
标准未强制 |
强制加密,强制HTTPS |
|
浏览器现状 |
已淘汰 |
广泛兼容 |
因队头阻塞默认禁用 |
主流标准 |
快速普及 |


1.3 http2
1.3.1 二进制分帧层
HTTP/2 在应用层与传输层之间引入了一个二进制分帧层。
- 文本转二进制:HTTP/1.x 的 ASCII 文本报文被转换为二进制格式。
- 帧:通信的最小单位。每个帧包含帧头和负载,帧头内包含流 ID。
- 消息:逻辑上的完整 HTTP 请求或响应,由一个或多个帧组成。
1.3.2 多路复用与流
- 流:应用协议自定义的,每个流有唯一的流 ID(奇数为客户端发起,偶数为服务器发起)。
- 交错传输:
- 在同一个 TCP 连接上,不同流的帧可以任意交错发送。
- 客户端发送多个帧,每个帧的流ID可以不同。
- 解决应用层队头阻塞:接收端根据 流 ID 将帧重组为完整的消息。流1 的大数据块传输不会阻塞 流2 的小数据块发送。
1.3.3 头部压缩 (HPACK)
- 问题:HTTP/1.x 头部冗余大(如 User-Agent, Cookie 重复传输),且未压缩。
- 机制:
- 静态表 & 动态表:维护索引表,将头部字段映射为整数索引。
- 哈夫曼编码:对头部值进行无损压缩。
- 上下文更新:发送端和接收端同步维护动态表状态,仅发送增量变化。
1.3.4 依赖与优先级
- 客户端可在 HEADERS 帧中指定流的依赖树(Parent Stream)和权重(1-256)。
- 服务器据此调度发送顺序,优先传输关键资源(如 HTML/CSS),但这只是建议性的,不保证绝对顺序。
1.3.5 局限性:传输层 TCP 队头阻塞
尽管应用层解决了阻塞,但底层仍依赖 TCP。
- TCP 特性:面向字节流、可靠、严格有序。
- 阻塞机制:若 TCP 序列号 N 的包丢失,接收端 TCP 栈会缓存 N+1 及之后的所有数据包,直到 N 重传成功。
- 后果:即使 HTTP/2 的 Stream 1 和 Stream 2 互不相关,只要底层的 TCP 包丢失,该连接上的所有 Stream 都会暂停交付给应用层。这就是传输层队头阻塞。
1.4 http3
HTTP/3 将传输层从 TCP 替换为基于 UDP 的 QUIC 协议。它将 TLS 1.3 和可靠传输逻辑直接集成在用户态库中。
1.4.1 协议栈重构
- HTTP/2: HTTP/2 -> TLS 1.3 -> TCP -> IP
- HTTP/3: HTTP/3 -> QUIC (内置 TLS 1.3) -> UDP -> IP
- 意义:绕过内核态 TCP 栈的限制,在应用层实现拥塞控制、重传和加密,迭代更灵活。
1.4.2 流级多路复用与独立可靠性
QUIC 用 UDP 在应用层实现了类似 TCP 的可靠传输,但粒度不同:
- 多流架构:QUIC 连接包含多个独立的 Streams。
- 独立序号空间:每个 Stream 有自己独立的字节偏移量和确认机制。
- 解决传输层队头阻塞:
- 若 Stream A 的某个 Packet 丢失,QUIC 仅重传该 Packet。
- Stream B、C 的数据包即使物理上紧随其后到达,也能立即交付给应用层,无需等待 Stream A 的重传。
- 结论:丢包影响仅限于当前流,不影响同一连接下的其他流。
1.4.3 0-RTT 握手与连接迁移
- 快速握手 (0-RTT):
- 利用 TLS 1.3 的会话恢复机制。客户端在第一个数据包中直接携带加密的应用数据。
- 若服务端接受,可直接处理请求并返回响应,实现 0-RTT 延迟。
- 连接迁移:
- 问题:TCP 使用 (SrcIP, SrcPort, DstIP, DstPort) 四元组标识连接。网络切换(WiFi->4G)导致 IP 变化,TCP 连接断开。
- QUIC 方案:使用 Connection ID (CID) 标识连接,与 IP/Port 解耦。
- 过程:客户端 IP 变更后,后续数据包携带相同的 CID,服务端识别后继续传输,无需重新握手。
1.4.4 头部压缩 (QPACK)
- 问题:HTTP/2 的 HPACK 依赖严格的帧顺序(动态表更新必须按序),若前一个帧丢失,后续帧无法解码,导致应用层队头阻塞复现。
- QPACK 改进:
- 引入独立的控制流来同步动态表更新。
- 允许头部块在不阻塞的情况下引用动态表条目。
- 即使更新指令丢失,仅影响依赖该指令的特定流,不阻塞其他流。
1.4.5 拥塞控制
- QUIC 在用户态实现了可插拔的拥塞控制算法(默认通常为 CUBIC 或 BBR)。
- 由于运行在用户态,开发者可以快速部署新的拥塞控制算法,无需等待操作系统内核升级。
2. https
|
端口号 |
80 |
443,防火墙通常只开放443给Web |
|
安全性 |
低,明文传输 |
高,加密传输 |
|
加密机制 |
无 |
SSL/TLS 协议(对称加密+非对称加密+哈希),建立连接前先交换密钥,后续数据全程加密 |
|
身份认证 |
无 |
数字证书 ,验证服务器身份 |
|
握手过程 |
TCP 3次握手 |
TCP 3次握手 + TLS 握手 |
|
HTTP/2支持 |
浏览器不支持,实际标准未强制但浏览器强制 |
浏览器强制要求,仅对HTTPS开启H2 |
|
HTTP/3支持 |
不支持 |
支持,HTTP/3 本身就是基于加密设计的 |





