1 Overview
网络的基本构件
任何网络都由三部分组成:
- 端系统(End System / Host):运行应用程序的机器。PC、手机、服务器、物联网设备
- 通信链路(Link):光纤、铜线、无线电、卫星。衡量指标是带宽(bit/s)
- 交换设备(Switch/Router):路由器在网络层转发(依据 IP),交换机在链路层转发(依据 MAC)
从端系统的视角看,中间那堆路由器/交换机就是一个黑盒的"云":我只管把数据交给网络边缘,网络负责送到。
两种交换方式
电路交换(Circuit Switching)
通信前先建立一条专用通路,整条链路的带宽被这条连接独占直到释放。传统电话网是典型。
- 优点:延迟稳定、无拥塞排队
- 缺点:静默期也占着资源,浪费
用多路复用提高利用率:
- FDM(频分):按频率切分,每路占一段频带
- TDM(时分):按时隙切分,每路周期性占用固定时隙
分组交换(Packet Switching)
数据切成分组(packet),每个分组独立路由,链路不预留资源,谁有数据谁发。互联网是典型。
- 优点:统计复用,资源利用率高(不是所有人同时满负荷)
- 缺点:可能排队、可能丢包,延迟不确定
对比:一条 1 Mbps 链路,10 个用户每个活跃时 100 kbps、只有 10% 时间活跃:
- 电路交换:最多支持 10 路(要预留)
- 分组交换:35 个用户时,同时活跃 ≥10 个的概率不到 0.04% → 实际能支持远多于 10 个
这就是互联网选分组交换的原因:牺牲确定性换利用率。
分层模型
为什么分层
- 降低复杂度:每层只解决一类问题
- 可替换:链路层从以太网换成 WiFi,上层无感
- 标准化:每层定义清晰的服务和接口
五层混合模型(实用版)
┌──────────────────────────────────────┐
│ 应用层 Application │ HTTP, DNS, SMTP, FTP, SSH
│ 为应用提供具体的网络服务 │ 报文 message
├──────────────────────────────────────┤
│ 传输层 Transport │ TCP, UDP, QUIC
│ 进程到进程的数据交付 │ 段 segment
├──────────────────────────────────────┤
│ 网络层 Network │ IP, ICMP, OSPF, BGP
│ 主机到主机的路由与寻址 │ 数据报 datagram
├──────────────────────────────────────┤
│ 链路层 Link │ Ethernet, WiFi(802.11), PPP
│ 相邻节点之间的帧传输 │ 帧 frame
├──────────────────────────────────────┤
│ 物理层 Physical │ 光纤, 双绞线, 同轴, 无线电
│ 比特在介质上的传输 │ 比特 bit
└──────────────────────────────────────┘每层的 PDU 名称
| 层 | 协议数据单元 | 英文 |
|---|---|---|
| 应用层 | 报文 | message |
| 传输层 | 报文段 | segment |
| 网络层 | 数据报 | datagram |
| 链路层 | 帧 | frame |
| 物理层 | 比特 | bit |
封装与解封装
发送端(自上而下加头):
[应用数据]
→ [HTTP头][应用数据] 应用层 PDU
→ [TCP头][HTTP头][应用数据] 传输层 PDU
→ [IP头][TCP头][HTTP头][应用数据] 网络层 PDU
→ [Eth头][IP头][TCP头][HTTP头][数据][FCS] 链路层帧
接收端(自下而上拆头):
每层的头只有对端的同层才理解。注意:每一层的头只被对端的同一层读取。路由器读到网络层就够了(要查 IP 决定下一跳),不会去解析 TCP 头——这就是分层的实际体现。
服务模型
面向连接 vs 无连接
| 面向连接(TCP) | 无连接(UDP) | |
|---|---|---|
| 建立连接 | 需要(三次握手) | 不需要 |
| 状态 | 双方维护连接状态 | 无状态 |
| 可靠性 | 保证送达 | 不保证 |
| 顺序 | 保证按序 | 不保证 |
| 开销 | 大(头 20B+,有握手和确认) | 小(头 8B) |
可靠数据传输的基本工具
无论哪一层,实现可靠性用的都是这几招的组合:
- 校验和(Checksum):检测比特错误
- 确认(ACK):接收方告诉发送方"收到了"
- 序号(Sequence Number):识别丢失和乱序
- 定时器 + 重传(Timeout/Retransmit):处理丢失
- 滑动窗口(Window):在不等待确认的情况下连续发送,提高吞吐
寻址:三种地址缺一不可
| 地址 | 层次 | 作用 | 长度 | 谁分配 |
|---|---|---|---|---|
| 域名 | 应用层 | 人类可读的名字 | 可变 | DNS 注册机构 |
| IP 地址 | 网络层 | 全网唯一的主机标识,用于路由 | IPv4 32 bit / IPv6 128 bit | IANA → RIR → ISP |
| MAC 地址 | 链路层 | 局域网内网卡标识,用于一跳之内 | 48 bit | 厂商烧录 |
| 端口号 | 传输层 | 主机上区分不同进程 | 16 bit | 操作系统/约定 |
为什么 IP 和 MAC 都要? 因为它们是不同层次的标识:
- IP 是"你在哪"(逻辑地址,随网络位置变化)——用于端到端路由
- MAC 是"你是谁"(物理地址,基本不变)——用于链路内交付
一跳之内用 MAC 找到下一个网卡,多跳之间用 IP 规划路径。每经过一个路由器,IP 头不变,链路层帧头尾全部重写(换 MAC、换帧格式)。
端口解决的是"数据到了主机,交给哪个进程"。熟知端口(0-1023):80 HTTP、443 HTTPS、22 SSH、53 DNS。
复用与分用
- 复用(Multiplexing):多个应用的数据都交给传输层,加上头部后共用网络层
- 分用(Demultiplexing):接收端传输层根据头部把数据交给正确的 socket
TCP 的分用靠四元组:
这四个值唯一确定一条 TCP 连接。所以:
- 服务器一个监听端口可以同时服务成千上万连接(客户端 IP/port 不同)
- 浏览器开多个标签访问同一网站,靠源端口区分
UDP 的分用靠二元组(dstIP, dstPort)——同一个目的端口的所有数据都给同一个 socket,不管从哪来。
延迟的四个来源
| 延迟 | 定义 | 公式 | 典型量级 |
|---|---|---|---|
| 处理 | 检查头、查表、差错检测 | — | 以下 |
| 排队 | 在输出队列等待 | 依赖流量强度 | ~ 秒 |
| 传输 | 把分组所有 bit 推上链路 | 1500B@1Gbps ≈ 12 | |
| 传播 | 信号在介质中传播 | 1000km 光纤 ≈ 5 ms |
排队延迟的关键参数:流量强度(分组长度 × 到达率 / 链路带宽)。
- 趋近 0:几乎不排队
- 趋近 1:延迟急剧上升(排队论的结论, 型增长)
1:队列无限增长,网络拥塞崩溃
这就是为什么带宽利用率不能设计到 100%——85% 以上排队延迟就开始爆炸了。
丢包
现实里路由器队列是有限的。队列满了,新到的分组被丢弃(tail drop,或 RED 随机早期丢弃)。
丢包后:
- TCP:检测并重传(因此吞吐下降)
- UDP:直接丢了,应用层自己扛(视频卡一下、游戏瞬移一下)
吞吐
瓶颈链路决定端到端吞吐。下载文件时,慢的不是服务器也不是你的网卡,而是中间最窄的那段。
看这个例子:传输延迟 0.8 s 远超传播延迟 5 ms。所以在高带宽长距离链路上,瓶颈往往是"把数据推上链路"的时间,而不是"在路上跑"的时间。反过来小包(如 RPC 请求)的瓶颈就是传播延迟。
协议与标准
**协议(Protocol)**定义三件事:
- 语法:报文格式、字段布局
- 语义:每个字段的含义、该做什么动作
- 时序(同步):事件发生的顺序
**RFC(Request for Comments)**是 IETF 的标准文档。著名的:
- RFC 791:IPv4
- RFC 793:TCP
- RFC 2616 / 7230-7235 / 9110:HTTP/1.1
- RFC 9000:QUIC
标准化组织:IETF(互联网)、IEEE 802(局域网,以太网/WiFi)、ITU-T(电信)、3GPP(蜂窝)。
网络的分类
按规模:
| 类型 | 全称 | 范围 |
|---|---|---|
| PAN | Personal Area Network | 个人设备,蓝牙 |
| LAN | Local Area Network | 一栋楼/园区,以太网/WiFi |
| MAN | Metropolitan Area Network | 城市 |
| WAN | Wide Area Network | 跨省跨国,运营商骨干 |
| Internet | — | 网络的网络 |
**互联网(小写 internet)**泛指"多个网络互连",**因特网(大写 Internet)**特指全球那个用 TCP/IP 的公共互联网。
网络边缘 vs 网络核心
- 边缘:端系统 + 接入网(家庭宽带、4G/5G、WiFi)
- 核心:运营商的路由器 mesh
按 端到端原则(End-to-End Argument):
能在端系统实现的功能,就应该放在端系统,不要放进网络核心。
因为核心要为所有应用服务,把特定功能(如可靠传输)塞进去,会让不需要它的应用也被拖累。TCP 放在端系统上,正是这一原则的体现。这条原则也是后来"网络中立性"讨论的理论基础之一。
一个完整的访问过程
浏览器输入 https://www.example.com 回车,到页面显示:
1. DNS 解析 : 域名 → IP(UDP,递归 + 迭代查询)
2. TCP 握手 : 三次握手建立连接(SYN → SYN-ACK → ACK)
3. TLS 握手 : 协商密钥、验证证书
4. HTTP 请求 : GET / HTTP/1.1
5. 服务器处理 : 生成响应
6. HTTP 响应 : 200 OK + HTML
7. 渲染 : 解析 HTML,发现子资源(CSS/JS/图片),重复 1-6
8. 连接复用/关闭这 8 步覆盖了几乎整门课。排查网络问题时,按顺序逐段定位(先 DNS 能不能解析,再 TCP 通不通,再 TLS 成不成,最后 HTTP)——这个思路比瞎猜有效得多。
常用排查命令
ping example.com # ICMP,测连通性和 RTT(可能被防火墙拦)
traceroute example.com # 逐跳看路径(Windows 上是 tracert)
dig example.com # DNS 查询详情(nslookup 也行)
curl -v https://example.com # 看完整 HTTP 交互和 TLS 握手
ss -tulnp # 本机监听/连接(netstat 的现代替代)
tcpdump -i any port 443 # 抓包看真实报文
openssl s_client -connect example.com:443 # 单独验证 TLS
iperf3 -c server # 测带宽抓包是最强的手段。当所有推理都解释不通时,看线上实际发的字节是什么。
常见坑
- 混淆带宽和延迟:加带宽对小文件传输几乎没用(延迟主导),对大文件才有用
- 以为 ping 通就代表服务正常:ICMP 通 ≠ TCP 端口通 ≠ 应用层正常(防火墙可能只放 ICMP)
- 忽略 MTU:VPN/隧道/GRE 会加头,导致有效 MTU 变小,大包被丢弃。症状是"小请求正常,大请求超时"
- TIME_WAIT 恐惧症:高并发短连接场景下 TIME_WAIT 堆积是正常现象,盲目调
tcp_tw_reuse可能引发 NAT 环境下的连接错乱 - 以为 localhost 不走协议栈:仍然走完整的 TCP/IP 栈(只是不经过网卡),所以防火墙规则和端口占用一样生效