深色模式
00 · 网络导读:两台机器怎么说话
网络这块最容易学成"协议名大杂烩"。避免的办法只有一个:始终盯着一个具体场景——"我敲下回车,页面出来了"。
一句话本质
网络要解决的是:两台互不认识的机器,如何把一段数据完整、按序、不重复地送到对方手上,中间还要穿过一堆会丢包、会堵车、会绕路的链路。
生活类比:寄快递
| 网络概念 | 快递 |
|---|---|
| IP 地址 | 收件地址(省市区门牌) |
| MAC 地址 | 这栋楼的门牌号(只在小区内有效) |
| 端口 | 房间号(同一个地址,不同的人收) |
| DNS | 查地址簿:把"张三"变成"某某路 8 号" |
| 路由 | 分拣中心,决定下一站发往哪个中转站 |
| TCP | 带签收、带编号、丢了重发的快递 |
| UDP | 塞进信箱就走,不管到不到 |
| HTTP | 包裹里装的东西 + 一张说明单 |
| TLS | 把箱子锁上,只有对方有钥匙 |
关键映射:IP 负责"送到哪栋楼",端口负责"送到哪个房间",TCP 负责"保证送到且不丢件",HTTP 负责"里面装的是什么"。
模块地图:5 篇怎么接
+-- 应用层 HTTP / HTTPS / DNS (04、05 篇)
| "里面装什么、怎么描述"
+-- 传输层 TCP / UDP (02、03 篇)
| "怎么保证不丢、不乱、不重复"
+-- 网络层 IP / ICMP / 路由 (01 篇)
| "怎么找到对方、怎么绕过拥堵"
+-- 链路层 以太网 / ARP / MAC (05 篇)
"这一跳怎么送到隔壁"为什么是 5 篇:
- 01 分层总纲:先建立"一次请求的全貌",它是整个模块的地图。这篇必须最先看。
- 02 连接管理:TCP 怎么建立和断开。三次握手四次挥手是面试第一高频。
- 03 可靠传输:连接建好了,怎么保证数据不丢不乱。滑动窗口、重传、拥塞控制。
- 04 HTTP/HTTPS:应用层到底传什么。版本演进、缓存、TLS。
- 05 DNS/ARP:两个"翻译官"。一个把域名翻成 IP,一个把 IP 翻成 MAC。
一条主线:输入 URL 之后发生了什么
这条线是整个网络模块的骨架,建议先通读一遍:
1. 浏览器解析 URL > 得到 域名 + 端口 + 路径
2. 查 DNS(05):域名 > IP 地址
+- 浏览器缓存 > 系统缓存 > hosts > 本地DNS > 根 > 顶级域 > 权威DNS
3. 建 TCP 连接(02):三次握手
4. (如果是 HTTPS)TLS 握手(04):协商密钥、验证证书
5. 发 HTTP 请求(04):GET /index.html HTTP/1.1 + 请求头
6. 数据往下走(01):
应用层 > 传输层加 TCP 头 > 网络层加 IP 头 > 链路层加 MAC 头
7. 查 ARP(05):下一跳的 IP 对应的 MAC 是多少
8. 经过若干路由器转发(每跳都拆到网络层再重新封装链路层)
9. 服务端收到,逐层解封装,交给监听该端口的进程
10. 服务端处理,返回响应,原路返回
11. 浏览器解析 HTML,发现还要加载 CSS/JS/图片 > 重复 3~10(复用连接)
12. 渲染页面这条线里,每一步都是一个面试题。而且它是把四个模块串起来的唯一线索——后面 一张图串起全部:一次请求的完整旅程 会把 OS 和数据库也接进来。
学习这个模块的方法
- 不要背协议格式,背"这个协议解决了什么麻烦"。TCP 头的每个字段都对应一个具体问题(序号>乱序,窗口>流控,校验和>损坏)。
- 一定要抓包看一次。
tcpdump或 Wireshark 看一眼真实的三次握手,比读十遍文字管用。 - 画时序图。握手挥手、滑动窗口、TLS 握手,这三张图必须能默画。
- 遇到"为什么"就去想"不这样会怎样"。网络协议的设计几乎全是"为了应对某种故障"。
和其他模块的连接
- < 来自 IO 模型与零拷贝:等设备的时候,CPU 在干什么:网络收发本质是进程在等 IO;socket 缓冲区就是内核里的那块内存
- < 来自 内核态与系统调用:用户程序怎么"申请"做事:
send/recv是系统调用,协议栈在内核态运行 - > 影响 SQL 执行与优化:一次数据库查询的往返,就是一次网络 RTT;跨机房部署时延迟是主要成本
- > 影响 工程实践:CDN、负载均衡、连接池、HTTP/2 多路复用,全部建立在这几篇之上
自测 3 问
Q1:为什么网络要分层?
点开看答案
三个理由:
- 解耦:换链路介质(网线换 WiFi)不影响 TCP;换应用协议(HTTP 换 WebSocket)不影响 IP。
- 各司其职:每层只解决一类问题,不用一个协议把"寻址 + 可靠 + 应用语义"全包了。
- 可替换:某一层出新技术(比如 QUIC 把可靠传输搬到 UDP 上),其他层不用动。
反过来说:分层也有代价——每层都要加头、拆头,有额外开销;而且层与层之间的信息不共享,导致优化困难(比如 TCP 不知道应用层已经超时了)。这也是 QUIC 出现的原因之一。
Q2:IP 和 MAC 有什么区别?为什么两个都要?
点开看答案
- IP 是逻辑地址:可以变(换网络就变),是"最终目的地",全局唯一,用于跨网络寻址。
- MAC 是物理地址:烧在网卡上,一般不变,是"这一跳的收件人",只在同一个局域网内有效。
为什么都要:IP 负责"从起点到终点的路线",MAC 负责"这一跳交给谁"。
类比:你要从北京寄到上海。IP 是"上海市某某路 8 号"(最终地址),MAC 是"当前这一站的下一站是哪个分拣中心"(每一跳都会换)。包裹每经过一个路由器,IP 头不变(源和目的 IP 不变),但 MAC 头会被重写成下一跳的 MAC。
Q3:TCP 和 UDP 该怎么选?
点开看答案
不是"TCP 好 UDP 差",是场景不同:
| 选 TCP | 选 UDP |
|---|---|
| 数据不能丢(文件、网页、转账) | 偶尔丢一点没关系(音视频、游戏位置同步) |
| 需要按序(文本、JSON) | 顺序不重要,或者应用层自己处理 |
| 不想自己实现重传 | 要极低延迟(重传反而更慢) |
| 连接数不多 | 要广播/多播(TCP 不支持) |
关键认知:UDP 不是"不可靠的 TCP",它是"什么都不管的传输层"。可靠、有序、拥塞控制全都要应用层自己实现——QUIC 就是这么干的(在 UDP 上重造了一个更好的 TCP)。
类比失效处 / 易错点
- "快递"类比会让人以为数据是"整包"发的。实际是切成一段段(MSS 通常 1460 字节),各自独立传输、可能乱序到达。
- "IP 是地址"会让人以为一个 IP 对应一台机器。实际 NAT 后面可能有几千台机器共享一个公网 IP;一个机器也可以有多个 IP。
- 端口不是"房间号"那么简单。端口标识的是"进程",但同一端口可以被不同协议(TCP/UDP)同时使用,这是两个独立的命名空间。
- "分层"不代表严格按层调用。实际实现里为了性能会跨层(比如 TCP 校验和用硬件卸载、应用层直接读网卡队列 DPDK)。
- OSI 七层是教学模型,实际用的是 TCP/IP 四层(或五层)。面试问"七层"就答七层,问"实际"就答四层,别混。
✅ 验收清单
- 能画出 TCP/IP 四层模型,每层说出 2 个代表协议
- 能用快递类比,把 IP / MAC / 端口 / DNS / TCP / HTTP 六个词一次讲对
- 能不看资料口述"输入 URL 之后发生了什么",至少 8 个步骤
- 能解释"为什么 IP 和 MAC 都要有",并说清路由器转发时哪个变哪个不变
- 能说出分层的好处和代价(代价要提到"层间信息不共享")
- 合上书,用自己的话讲 3 分钟,中途不卡壳