一、用户输入URL与浏览器准备(应用层 - HTTP)
-
输入与解析
用户在浏览器地址栏输入https://www.example.com/index.html,浏览器解析URL:- 协议:
https(HTTP + TLS) - 域名:
www.example.com - 路径:
/index.html - 默认端口:443(HTTPS)
- 协议:
-
缓存检查
浏览器依次检查:- Service Worker 缓存
- HTTP 强缓存(
Cache-Control/Expires) - 协商缓存(
ETag/Last-Modified) - DNS 缓存(本地 hosts 文件、操作系统 DNS 缓存) 若缓存命中则直接渲染,否则进入网络请求流程。
图片来自于:2.2 键入网址到网页显示,期间发生了什么? | 小林coding | Java面试学习
编辑
二、DNS解析(域名 → IP 地址)
DNS 是应用层协议,负责将人类可读的域名转换为机器可识别的 IP 地址:
-
递归查询(客户端 → 本地DNS服务器)
浏览器向本地 DNS 服务器(如 114.114.114.114)发起递归查询:客户端只发一次请求,由本地 DNS 服务器负责完成全部查询并返回最终结果。 -
迭代查询(本地DNS服务器 → 根/顶级/权威DNS)
本地 DNS 服务器依次向以下服务器发起迭代查询:- 根域名服务器(.):返回
.com顶级域服务器地址 - 顶级域服务器(.com):返回
example.com权威服务器地址 - 权威域名服务器(example.com):返回
www.example.com的 A 记录(IPv4 地址)或 AAAA 记录(IPv6 地址)
- 根域名服务器(.):返回
-
结果缓存
本地 DNS 服务器将结果缓存(TTL 时间内),并返回给浏览器。浏览器也将结果存入本地 DNS 缓存。
💡 关键点:DNS 查询使用 UDP 协议(端口 53),仅在区域传输等特殊场景用 TCP。
三、ARP解析(IP → MAC 地址)
获得目标服务器 IP 后,需确定数据链路层的物理地址(MAC):
- 同一局域网内
若目标 IP 与本机在同一网段,浏览器通过 ARP 协议广播请求:"谁拥有 IP 192.168.1.100?请回复 MAC 地址"。目标设备回复其 MAC 地址。 - 跨网段(需经网关)
若目标 IP 不在同一网段(如公网服务器),则向默认网关(路由器)发起 ARP 请求,获取网关的 MAC 地址。
四、TCP 三次握手(建立可靠连接)
下图来自:2.2 键入网址到网页显示,期间发生了什么? | 小林coding | Java面试学习
TCP 报文头部的格式:
编辑
编辑
HTTP 基于 TCP,需先建立连接:
| 步骤 | 方向 | 报文 | 关键字段 |
|---|---|---|---|
| 1 | 客户端 → 服务器 | SYN | SYN=1, seq=x |
| 2 | 服务器 → 客户端 | SYN+ACK | SYN=1, ACK=1, seq=y, ack=x+1 |
| 3 | 客户端 → 服务器 | ACK | ACK=1, seq=x+1, ack=y+1 |
- 为什么是三次?
两次握手无法防止历史连接请求突然到达造成资源浪费;三次是保证双向通信能力的最小次数
。 - 全双工确认:双方各自确认对方的发送/接收能力。
🔒 HTTPS 额外步骤:三次握手后还需进行 TLS 握手(证书验证、密钥交换),通常需 1-2 个 RTT。
编辑
编辑
五、协议栈封装与数据传输
数据从应用层向下逐层封装,形成完整数据包:
┌──────────────────────────────────────┐
│ 应用层:HTTP GET /index.html │ ← 添加 HTTP 头部(Host, User-Agent...)
├──────────────────────────────────────┤
│ 传输层:TCP │ ← 添加 TCP 头部(源/目的端口、序列号、ACK)
├──────────────────────────────────────┤
│ 网络层:IP │ ← 添加 IP 头部(源/目的 IP、TTL、协议号)
├──────────────────────────────────────┤
│ 数据链路层:以太网帧 │ ← 添加 MAC 头部(源/目的 MAC)、FCS 校验
├──────────────────────────────────────┤
│ 物理层:0/1 电信号 │ ← 网卡将帧转换为电信号/光信号
└──────────────────────────────────────┘
- 封装原则:每层添加本层头部(有时加尾部),下层为上层提供服务。
- 分片:若数据超过 MTU(通常 1500 字节),IP 层会进行分片。
六、网卡、交换机、路由器的协作
1. 网卡(NIC)
- 将封装好的以太网帧转换为电信号(有线)或无线电波(Wi-Fi),通过物理介质(网线/光纤)发送。
- 接收时执行反向操作:电信号 → 数字信号 → 去封装。
2. 交换机(数据链路层设备)
- 根据目的 MAC 地址查询 MAC 地址表,将帧转发到对应端口。
- 仅在同一局域网内工作,不修改 IP 头部。
- 若未知目的 MAC,执行泛洪(向所有端口广播)。
3. 路由器(网络层设备)
-
根据目的 IP 地址查询路由表,决定下一跳。
-
关键操作:
- 解封装到 IP 层,检查 TTL(每经过一跳减 1,为 0 则丢弃)
- 重新封装数据链路层帧(更换源/目的 MAC 为当前跳的接口 MAC)
- 转发到下一网络
-
跨越不同网络(如从家庭网络 → 运营商网络 → 互联网骨干网)。
🌐 路径示例:
客户端 → 家用路由器 → 运营商接入路由器 → 骨干网路由器 → CDN 节点 → 源站服务器
七、服务器处理与响应
-
接收与解封装
服务器网卡接收电信号 → 逐层向上解封装(物理层 → 数据链路层 → 网络层 → 传输层)。 -
TCP 连接确认
内核根据目标端口(443)将数据交给对应进程(如 Nginx)。 -
HTTP 请求处理
- 解析 HTTP 请求行、头部、Body
- 执行业务逻辑(查询数据库、调用 API)
- 生成 HTTP 响应(状态码 200、HTML 内容、Content-Type 等)
-
响应发送
响应数据沿反向路径返回客户端:服务器 → 路由器 → 交换机 → 客户端网卡,每跳重新封装数据链路层帧。
八、浏览器渲染页面
- 解析 HTML → 构建 DOM 树
- 解析 CSS → 构建 CSSOM 树(CSS 不阻塞 DOM 解析,但阻塞渲染)
- 合并 DOM + CSSOM → 生成渲染树(Render Tree)
- 布局(Layout) :计算元素几何位置
- 绘制(Paint) :生成像素
- 合成(Composite) :分层合成最终画面
⚡ 关键优化:现代浏览器采用流式解析,遇到
<script>会阻塞 HTML 解析(除非加async/defer)。
九、TCP 四次挥手(断开连接)
| 步骤 | 方向 | 报文 | 说明 |
|---|---|---|---|
| 1 | 客户端 → 服务器 | FIN | 客户端请求关闭连接 |
| 2 | 服务器 → 客户端 | ACK | 服务器确认收到 FIN |
| 3 | 服务器 → 客户端 | FIN | 服务器数据发完,请求关闭 |
| 4 | 客户端 → 服务器 | ACK | 客户端确认,进入 TIME-WAIT(2MSL) |
- 为什么四次?
TCP 是全双工协议,每个方向需独立关闭。服务器收到 FIN 后可能还有数据要发送,不能立即回复 FIN,需先回 ACK,等数据发完再发 FIN。 - TIME-WAIT 作用:确保最后一个 ACK 能到达;防止旧连接数据包干扰新连接。
完整流程图解
用户输入URL
↓
DNS解析(递归+迭代)→ 获得IP
↓
ARP解析 → 获得MAC(网关或目标)
↓
TCP三次握手 → 建立连接
↓
HTTP请求(应用层)
↓
协议栈封装:HTTP → TCP → IP → MAC
↓
网卡 → 电信号
↓
交换机(基于MAC转发)
↓
路由器(基于IP路由,更换MAC)
↓(跨越多跳网络)
服务器接收 → 解封装 → 处理请求 → 生成响应
↓(反向路径)
客户端接收响应 → 浏览器渲染页面
↓
TCP四次挥手 → 断开连接
关键总结
| 层级 | 协议/设备 | 核心作用 | 地址类型 |
|---|---|---|---|
| 应用层 | HTTP/HTTPS, DNS | 提供用户服务 | 域名/URL |
| 传输层 | TCP/UDP | 端到端可靠传输 | 端口号 |
| 网络层 | IP | 跨网络寻址与路由 | IP 地址 |
| 数据链路层 | 以太网, ARP | 局域网内帧传输 | MAC 地址 |
| 物理层 | 网卡 | 电信号传输 | 无地址 |
整个过程体现了 "分层设计" 的精髓:每层只关心本层协议,通过封装/解封装实现端到端通信,同时网络设备(交换机/路由器)在不同层次完成转发,最终实现从"键入网址"到"页面呈现"的完整旅程。