vault backup: 2026-05-17 22:27:07
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
---
|
||||
tags: [计算机网络, OSI模型, TCP/IP, 网络分层]
|
||||
create time: 2026-05-17 22:10
|
||||
---
|
||||
|
||||
# OSI 七层 vs TCP/IP 四层模型
|
||||
|
||||
## 概述
|
||||
|
||||
OSI(Open Systems Interconnection)和 TCP/IP 是理解计算机网络的两种经典分层模型。OSI 提供了一套理论化的参考框架,而 TCP/IP 则是实际运行在因特网上的协议栈。理解两者的映射关系,有助于我们在设计系统和排查问题时建立正确的抽象层次。
|
||||
|
||||
> [!QUESTION] 为什么现实用五层模型而不是 OSI?
|
||||
> OSI 的七层理论很完美,但实现起来复杂到几乎不可能。TCP/IP 只有四层,又太粗。于是教学上采用折中的「五层模型」:把 OSI 的应用/表示/会话三层合并为应用层,保留传输层、网络层、链路层、物理层——刚好够表达所有关键概念。
|
||||
|
||||
## OSI 七层模型
|
||||
|
||||
### 分层结构
|
||||
|
||||
| 层级 | 名称 | PDU(协议数据单元) | 核心职责 |
|
||||
|------|------|-----|---------|
|
||||
| 7 | 应用层 | 数据(Data) | 为用户提供网络服务接口(HTTP、FTP、SMTP) |
|
||||
| 6 | 表示层 | 数据 | 数据格式转换、加密解密、压缩解压 |
|
||||
| 5 | 会话层 | 数据 | 建立/维护/终止会话(会话令牌、检查点) |
|
||||
| 4 | 传输层 | 段(Segment) | 端到端可靠传输、流量控制、差错控制 |
|
||||
| 3 | 网络层 | 包(Packet) | 路由选择、逻辑寻址(IP 地址) |
|
||||
| 2 | 数据链路层 | 帧(Frame) | 物理寻址(MAC)、相邻节点间的帧传输 |
|
||||
| 1 | 物理层 | 比特(Bit) | 电气特性、机械接口、光电信号转换 |
|
||||
|
||||
```mermaid
|
||||
graph BT
|
||||
subgraph "传输中封装"
|
||||
D["应用层 Data"] --> L6["表示层: 加密+压缩"]
|
||||
L6 --> L5["会话层: 建立/维护/结束会话"]
|
||||
L5 --> S["传输层 Segment"]
|
||||
S --> P["网络层 Packet"]
|
||||
P --> F["链路层 Frame"]
|
||||
F --> B["物理层 Bitstream"]
|
||||
end
|
||||
|
||||
style D fill:#DDA0DD
|
||||
style S fill:#FFD700
|
||||
style F fill:#98FB98
|
||||
style B fill:#B0C4DE
|
||||
```
|
||||
|
||||
### 每层经典协议对照表
|
||||
|
||||
| 层 | 协议 | 作用场景 |
|
||||
|----|------|---------|
|
||||
| 应用层 | HTTP, DNS, SMTP, FTP, SSH, WebSocket | 应用间通信 |
|
||||
| 表示层 | TLS/SSL, JPEG, MPEG, ASN.1 | 数据格式化与加密 |
|
||||
| 会话层 | NetBIOS, RTP, SIP | 多路复用与同步 |
|
||||
| 传输层 | TCP, UDP, SCTP | 端到端数据传输 |
|
||||
| 网络层 | IP, ICMP, IGMP, ARP* | 跨网段路由转发 |
|
||||
| 链路层 | Ethernet, Wi-Fi (802.11), VLAN, PPP | 相邻设备帧传输 |
|
||||
| 物理层 | USB, RS-232, 光纤, Cat6 网线 | 物理信号传输 |
|
||||
|
||||
> [!note] ARP 到底在第几层?
|
||||
> ARP 将 IP 地址解析为 MAC 地址,跨越了网络层和链路层的边界。OSI 将其放在**网络层下方、链路层上方**的"夹层"位置。现代观点常把它视为网络层的一部分。
|
||||
|
||||
## TCP/IP 四层模型
|
||||
|
||||
### 分层结构
|
||||
|
||||
| 层级 | 对应 OSI | 核心协议 | 核心职责 |
|
||||
|------|----------|---------|---------|
|
||||
| 应用层 | 7+6+5 层合并 | HTTP, DNS, SMTP, SSH | 面向应用的协议栈 |
|
||||
| 传输层 | 4 层 | TCP, UDP | 端到端连接管理 |
|
||||
| 网络层 | 3 层 | IP, ICMP, ARP | 分组路由与寻址 |
|
||||
| 网络接口层 | 2+1 层合并 | Ethernet, Wi-Fi | 帧传输与物理介质 |
|
||||
|
||||
### 为何 OSI 没赢下标准之战
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["OSI 七层模型<br/>ISO 标准"] --> B{谁先落地?}
|
||||
B -->|"1970s 末"| C["TCP/IP 已部署在 ARPANET"]
|
||||
B -->|"1980s 后"| D["OSI 标准太多太复杂"]
|
||||
C --> E["事实标准 ✅"]
|
||||
D --> E
|
||||
style E fill:#98FB98,color:#000
|
||||
```
|
||||
|
||||
- **先发优势**:ARPANET / Internet 先用上了 TCP/IP,基础设施已经建成
|
||||
- **简单粗暴**:TCP/IP 只关心能不能跑通,不搞复杂的标准化流程
|
||||
- **开源免费**:Berkeley BSD Unix 内嵌 TCP/IP 协议栈,免费分发
|
||||
- **OSI 的反面教材**:层层审批导致协议膨胀(X.400 邮件、X.25 分组交换),开发者根本懒得用
|
||||
|
||||
## 五层教学模型
|
||||
|
||||
这是教材中最常用的模型,取两者精华:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["应用层 — Application<br/>HTTP DNS SMTP SSH FTP SMTP POP3 IMAP WebSocket"] --> T["传输层 — Transport<br/>TCP UDP SCTP"]
|
||||
T --> N["网络层 — Internet<br/>IP IPv6 ICMP ARP NAT"]
|
||||
N --> D["链路层 — Link<br/>Ethernet Wi-Fi 802.11 VLAN HDLC PPP"]
|
||||
D --> P["物理层 — Physical<br/>双绞线 光纤 无线电 IEEE 802.15"]
|
||||
style A fill:#DDA0DD
|
||||
style T fill:#FFD700
|
||||
style N fill:#87CEEB
|
||||
style D fill:#98FB98
|
||||
style P fill:#B0C4DE
|
||||
```
|
||||
|
||||
## 数据包逐层穿越过程
|
||||
|
||||
以你发送一封电子邮件为例:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as 你的邮件客户端
|
||||
participant T as TCP层
|
||||
participant I as IP层
|
||||
participant L as 以太网层
|
||||
participant Router as 路由器
|
||||
participant R as 接收方
|
||||
|
||||
App->>T: SMTP 邮件内容 (Data)
|
||||
T->>T: 加 TCP 首部 (Header + Data → Segment)
|
||||
T->>I: 传递 Segment
|
||||
I->>I: 加 IP 首部 (Header + Segment → Packet)
|
||||
I->>L: 传递 Packet
|
||||
L->>L: 加以太网帧头帧尾 (Header + Packet + FCS → Frame)
|
||||
L->>Router: 通过网线发送 Frame
|
||||
Router->>Router: 拆帧 → 查路由表 → 重新封帧
|
||||
Router->>R: 转发给接收方
|
||||
R->>L: 解包 → IP层校验 → TCP重组 → 提取 SMTP
|
||||
R->>App: 邮件到达收件箱
|
||||
```
|
||||
|
||||
> [!tip] 封装 = 套娃;解封装 = 剥壳
|
||||
> 每一层只知道自己那一层的 header 是什么格式,对其他层的内容一无所知。这就是**层间透明**原则。
|
||||
|
||||
## 关联笔记
|
||||
|
||||
- [[hhs/NETWORK/02-以太网帧结构]] — 链路层帧的详细结构
|
||||
- [[hhs/NETWORK/03-IPv4协议详解]] — 网络层 IP 数据包格式
|
||||
- [[hhs/NETWORK/04-TCP状态机详解]] — 传输层 TCP 连接管理
|
||||
- [[hhs/NETWORK/05-HTTP请求响应]] — 应用层协议细节
|
||||
@@ -0,0 +1,126 @@
|
||||
---
|
||||
tags: [计算机网络, 数据封装, 网络分层]
|
||||
create time: 2026-05-17 22:20
|
||||
---
|
||||
|
||||
# 数据封装与解封装
|
||||
|
||||
## 概述
|
||||
|
||||
数据在发送端逐层加上头部(Header),就像装快递盒子:最里层是商品,外面一层一层套纸箱、贴面单、打托盘。到达接收端后,每一层剥掉自己的那层包装,只把原始内容交给上层处理。这个"套娃+拆箱"的过程就是 **封装(Encapsulation)** 和 **解封装(Decapsulation)**。
|
||||
|
||||
> [!QUESTION] 为什么每层都要加头?
|
||||
> 因为每层需要知道如何管理自己的事务——传输层关心连接状态,网络层关心路由寻址,链路层关心物理介质。这些元信息必须跟在数据前面,让每一层都能正确解读并转发。
|
||||
|
||||
## 数据包尺寸变化轨迹
|
||||
|
||||
以发送一个 HTTP GET 请求为例,追踪尺寸变化:
|
||||
|
||||
| 层级 | 操作 | 数据结构 | 新增首部大小 | 累计大小 |
|
||||
|------|------|---------|-------------|---------|
|
||||
| 应用层 | HTTP GET 报文 | `GET / HTTP/1.1\r\nHost: example.com\r\n\r\n` | — | ~40 bytes |
|
||||
| 传输层 (TCP) | + TCP Header | Segment | 20 bytes | ~60 bytes |
|
||||
| 网络层 (IP) | + IP Header | Packet | 20 bytes (IPv4) | ~80 bytes |
|
||||
| 链路层 (Ethernet) | + Eth Header + FCS | Frame | 14 + 4 = 18 bytes | ~98 bytes |
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
H["HTTP GET 40B"] --> T["+ TCP Header 20B<br/>Segment 60B"]
|
||||
T --> I["+ IP Header 20B<br/>Packet 80B"]
|
||||
I --> E["+ Ethernet HDR 14B + FCS 4B<br/>Frame 98B"]
|
||||
E --> B["98 个 Bit 在网线上传输"]
|
||||
|
||||
style H fill:#DDA0DD
|
||||
style T fill:#FFD700
|
||||
style I fill:#87CEEB
|
||||
style E fill:#98FB98
|
||||
```
|
||||
|
||||
## 发送端:逐层封装
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as HTTP 应用
|
||||
participant TCP as TCP Socket
|
||||
participant IP as 网络层 IP
|
||||
participant ETH as 以太网驱动
|
||||
|
||||
App->>TCP: write("GET / HTTP/1.1...")
|
||||
Note over TCP: 分配 seq/ack, state=ESTABLISHED
|
||||
TCP->>IP: 传递 Segment (daddr=x.x.x.x, sport=1234, dport=80)
|
||||
Note over IP: 查路由表 → 下一跳网关
|
||||
IP->>ETH: 传递 Packet (dst_mac=?, src_ip=192.168.1.100, dst_ip=93.184.216.34)
|
||||
Note over ETH: ARP 解析 → dst_mac=aabb.ccdd.eeff
|
||||
ETH->>ETH: 拼接 源MAC+目的MAC+EtherType+Payload+FCS
|
||||
ETH-->>App: sendto() 返回 → 帧已发出 ✅
|
||||
```
|
||||
|
||||
### Ethernet II 帧完整结构
|
||||
|
||||
```
|
||||
Offset Size Field 说明
|
||||
────── ──── ───────────────── ─────────────────────────────
|
||||
0 6 Dest MAC Address 目标 MAC 地址
|
||||
6 6 Source MAC Address 源 MAC 地址
|
||||
12 2 EtherType 0x0800=IPv4 / 0x86DD=IPv6 / 0x0806=ARP
|
||||
14 N Payload IP 包(最大 1500 字节)
|
||||
14+N 4 FCS CRC-32 帧校验序列(接收端自动验证)
|
||||
```
|
||||
|
||||
总长度范围:**64 ~ 1518 bytes**(不含 VLAN Tag;有 VLAN Tag 则上限 1522)。
|
||||
|
||||
> [!note] MTU = 1500 是什么意思?
|
||||
> MTU(Maximum Transmission Unit)是链路层允许的最大 Payload 大小,即 IP 包的最大体积。超过会被分片(Fragmentation),但分片会降低性能且增加丢包风险——这也是现代应用层(如 TLS、gRPC)倾向于小包传输的原因。
|
||||
|
||||
## 接收端:逐层解封装
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant ETH as 网卡收到 Frame
|
||||
participant IP as 剥离以太网头
|
||||
participant TCP as 剥离 TCP 头
|
||||
participant App as 提取 HTTP 数据
|
||||
|
||||
ETH->>IP: 校验 FCS OK → 取 EtherType=0x0800 → 剥离以太网头
|
||||
IP->>TCP: 校验 IP Checksum → 取 Protocol=6(TCP) → 剥离 IP 头
|
||||
TCP->>App: 按 Sequence Number 重组 → 剥离 TCP 头
|
||||
App->>App: 解析 "GET / HTTP/1.1..." 🎉
|
||||
```
|
||||
|
||||
每层的动作可以概括为三步:
|
||||
|
||||
1. **检查**:校验和是否正确?mac/ip/port 是否指向自己?
|
||||
2. **剥离**:去掉本层的 Header(必要时 Tail 如 FCS)
|
||||
3. **移交**:将剩余的 Payload 交给上层协议处理
|
||||
|
||||
## 各层 PDU 对照表
|
||||
|
||||
| OSI 名称 | PDU | TCP/IP 对应 | 关键标识字段 |
|
||||
|----------|-----|-------------|-------------|
|
||||
| 数据 (Data) | 报文段 | 应用层消息 | — |
|
||||
| 段 (Segment) | TCP Segment | 传输层 PDU | 源端口 + 目的端口 |
|
||||
| 包 (Packet) | IP Datagram | 网络层 PDU | 源 IP + 目的 IP + Protocol |
|
||||
| 帧 (Frame) | Ethernet Frame | 链路层 PDU | 源 MAC + 目的 MAC + EtherType |
|
||||
| 比特流 (Bits) | Bitstream | 物理层信号 | 电信号 / 光脉冲 |
|
||||
|
||||
## NAT 场景下的封装变化
|
||||
|
||||
NAT 路由器修改了中间层的地址:
|
||||
|
||||
```
|
||||
发送端内部主机 NAT 路由器 外部 Web 服务器
|
||||
┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐
|
||||
│ Src IP: 10.0.0.5:45678 │ │ SNAT: 改写 Src IP │ │ Dst IP: 203.0.113.1:80 │
|
||||
│ Dst IP: 203.0.113.1:80 │ → │ │ → │ │
|
||||
│ │ │ → Src IP: 8.8.8.8:45678 │ │ ← Src IP: 203.0.113.1:80 │
|
||||
│ │ │ → Dst IP: 203.0.113.1:80 │ │ → Src IP: 10.0.0.5:45678 │
|
||||
└──────────────────────┘ └──────────────────────┘ └──────────────────────┘
|
||||
```
|
||||
|
||||
注意:NAT 不触碰应用层载荷,只是在中途修改了 IP 和 TCP 端口。这也意味着 **传输层的 Checksum 需要重新计算**。
|
||||
|
||||
## 关联笔记
|
||||
|
||||
- [[hhs/NETWORK/OSI与TCP-IP模型对比]] — 分层模型的起源与对比
|
||||
- [[hhs/NETWORK/IPv4协议详解]] — IP 包的详细格式
|
||||
- [[hhs/NETWORK/TCP状态机详解]] — TCP 段的结构与状态管理
|
||||
@@ -0,0 +1,169 @@
|
||||
---
|
||||
tags: [计算机网络, MAC地址, IP地址, 端口号]
|
||||
create time: 2026-05-17 22:30
|
||||
---
|
||||
|
||||
# 寻址体系:MAC / IP / Port
|
||||
|
||||
## 概述
|
||||
|
||||
网络中的每个端点需要三层地址才能精确定位到一个进程:**MAC 地址**(物理层/链路层)定位到哪台设备、**IP 地址**(网络层)定位到哪个子网、**端口号**(传输层)定位到哪个进程。三层地址组合起来,就是经典的 `ip:port` 定位公式。
|
||||
|
||||
> [!QUESTION] 为什么需要三种地址?一层不够吗?
|
||||
> 每种地址解决不同尺度的问题。MAC 在同一个广播域内有效,但路由器不转发广播——跨网段必须用 IP 路由。IP 能到达目标主机,但不区分进程——同一台服务器可能跑着 Web、数据库、邮件等多个服务,所以需要端口来分发。
|
||||
|
||||
## 一、MAC 地址(48 位)
|
||||
|
||||
### 基本结构
|
||||
|
||||
```
|
||||
前 3 字节 后 3 字节
|
||||
───────────── ─────────────
|
||||
OUI (厂商编号) NIC 序列号
|
||||
由 IEEE 分配 由厂商自定
|
||||
```
|
||||
|
||||
示例:`aabb.ccdd.eeff` = `AA:BB:CC:DD:EE:FF`
|
||||
- 前三个字节 `AA:BB:CC` → OUI,代表厂商
|
||||
- 后三个字节 `DD:EE:FF` → 设备唯一序列
|
||||
|
||||
### MAC 地址类型
|
||||
|
||||
| 类型 | 格式 | 含义 |
|
||||
|------|------|------|
|
||||
| 单播 | LSB=0 | 发给单个设备 |
|
||||
| 广播 | `ff:ff:ff:ff:ff:ff` | 发给局域网内所有设备 |
|
||||
| 组播 | LSB=1 | 发给一组设备 |
|
||||
|
||||
### ARP 地址解析
|
||||
|
||||
当知道一个主机的 **IP 地址** 时,需要通过 ARP 协议找到它的 **MAC 地址**。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Src as 源主机<br/>192.168.1.10/?.mac
|
||||
participant Bcast as 局域网广播
|
||||
participant Dst as 目标主机<br/>192.168.1.20/aa:bb:cc:11:22:33
|
||||
participant Cache as 源主机 ARP 缓存
|
||||
|
||||
Src->>Bcast: ARP Request "192.168.1.20 是谁?→ ff:ff:ff:ff:ff:ff"
|
||||
Dst-->>Src: ARP Reply "我是!MAC = aa:bb:cc:11:22:33"
|
||||
Src->>Cache: 写入缓存条目 (TTL ≈ 15~30 分钟)
|
||||
Note over Src,Dst: 之后的通信直接用此 MAC,不再发 ARP
|
||||
```
|
||||
|
||||
### ARP 缓存查看与管理
|
||||
|
||||
```bash
|
||||
# Linux
|
||||
$ ip neigh show # 等价于 arp -n
|
||||
192.168.1.20 dev eth0 lladdr aa:bb:cc:dd:ee:ff STALE
|
||||
|
||||
$ ip neigh del 192.168.1.20 dev eth0 # 删除缓存条目
|
||||
|
||||
# macOS / Windows
|
||||
$ arp -a
|
||||
```
|
||||
|
||||
## 二、IP 地址(IPv4 32 位 / IPv6 128 位)
|
||||
|
||||
### IPv4 地址结构
|
||||
|
||||
```
|
||||
版本(4 bits) IHL(4 bits) DSCP(8 bits) Total Length(16 bits)
|
||||
...
|
||||
Identification(16 bits) | DF/MF | Fragment Offset(13 bits)
|
||||
TTL(8 bits) | Protocol(8 bits) | Header Checksum(16 bits)
|
||||
Source Address(32 bits)
|
||||
Destination Address(32 bits)
|
||||
Options (可选)...
|
||||
```
|
||||
|
||||
### IPv4 vs IPv6
|
||||
|
||||
| 特性 | IPv4 | IPv6 |
|
||||
|------|------|------|
|
||||
| 地址长度 | 32 bit (4 字节) | 128 bit (16 字节) |
|
||||
| 地址数量 | ~43 亿 (2³²) | ~3.4×10³⁸ (2¹²⁸) |
|
||||
| 表示法 | `192.168.1.1` | `2001:0db8::1` |
|
||||
| 首部固定长度 | 20 bytes(可变选项更长) | 40 bytes(固定) |
|
||||
| Checksum | ✅ 有 | ❌ 无(依赖上层校验) |
|
||||
| NAT | 广泛使用(缓解地址耗尽) | 不需要(地址充足) |
|
||||
| SLAAC | — | 支持无状态自动配置 |
|
||||
| 组播 | 有限支持 | 原生支持 |
|
||||
|
||||
### IP 地址分类(历史)
|
||||
|
||||
| 类别 | 首字节范围 | 默认掩码 | 可用主机数 | 用途 |
|
||||
|------|-----------|---------|-----------|------|
|
||||
| A | 1–126 | /8 | 16,777,214 | 大型组织 |
|
||||
| B | 128–191 | /16 | 65,534 | 中型组织 |
|
||||
| C | 192–223 | /24 | 254 | 小型网络 |
|
||||
| D | 224–239 | — | — | 组播 |
|
||||
| E | 240–255 | — | — | 保留 |
|
||||
|
||||
> [!warning] CIDR 已淘汰分类编址
|
||||
> 现代网络全部使用 **CIDR(Classless Inter-Domain Routing)** 无类编址,子网掩码可以是任意位数(如 /23、/27)。
|
||||
|
||||
## 三、端口号(16 位)
|
||||
|
||||
### 端口范围
|
||||
|
||||
| 范围 | 名称 | 说明 |
|
||||
|------|------|------|
|
||||
| 0–1023 | 熟知端口 (Well-Known) | 预分配给标准服务(HTTP:80, HTTPS:443, SSH:22, DNS:53) |
|
||||
| 1024–49151 | 注册端口 (Registered) | 申请注册的商业软件 |
|
||||
| 49152–65535 | 动态端口 (Ephemeral) | 客户端临时分配,用完即释放 |
|
||||
|
||||
### 服务端 vs 客户端端口
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Client["客户端 192.168.1.100:54321"] -->|"SYN"| Server["服务端 10.0.0.1:80"]
|
||||
Server -->|"SYN-ACK"| Client
|
||||
Client -->|"ACK"| Server
|
||||
|
||||
style Client fill:#DDA0DD,color:#000
|
||||
style Server fill:#98FB98,color:#000
|
||||
```
|
||||
|
||||
- **服务端端口**:固定且知名(如 80),告诉客户端"我在哪"
|
||||
- **客户端端口**:操作系统动态分配(49152–65535),保证连接的唯一标识 `(src_ip, src_port, dst_ip, dst_port)`
|
||||
|
||||
### 常见端口速查
|
||||
|
||||
| 端口 | 协议 | 服务 |
|
||||
|------|------|------|
|
||||
| 21 | FTP | 文件传输控制 |
|
||||
| 22 | SSH | 安全远程登录 |
|
||||
| 25 | SMTP | 邮件发送 |
|
||||
| 53 | DNS | 域名解析 |
|
||||
| 80 | HTTP | Web 网站 |
|
||||
| 443 | HTTPS | 加密 Web |
|
||||
| 993 | IMAPS | 加密邮件收取 |
|
||||
| 3306 | MySQL | 数据库 |
|
||||
| 5432 | PostgreSQL | 数据库 |
|
||||
| 6379 | Redis | 缓存 |
|
||||
| 8080 | HTTP Alt | Web 备用端口 |
|
||||
|
||||
## 四、完整寻址链:从请求到进程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
S["你在浏览器输入 example.com"] -->|"DNS 查询"| A["DNS 返回 93.184.216.34"]
|
||||
A -->|"TCP 三次握手"| B["建立 TCP 连接<br/>src:192.168.1.100:54321 → dst:93.184.216.34:80"]
|
||||
B -->|"以太网帧头"| C["Dst MAC: router的出口MAC<br/>Src MAC: 本机MAC"]
|
||||
C -->|"ARP缓存"| D["如果没缓存,先发ARP请求"]
|
||||
D -->|"发送 HTTP GET"| E["Web 服务器的 PID 1234<br/>nginx worker 进程读取数据"]
|
||||
|
||||
style S fill:#DDA0DD,color:#000
|
||||
style E fill:#98FB98,color:#000
|
||||
```
|
||||
|
||||
**结论:** 三层地址缺一不可——没有 IP 找不到机器,没有 MAC 连不上网线,没有端口不知道该交给哪个进程。
|
||||
|
||||
## 关联笔记
|
||||
|
||||
- [[hhs/NETWORK/OSI与TCP-IP模型对比]] — 三层地址对应 OSI 的不同层级
|
||||
- [[hhs/NETWORK/IPv4协议详解]] — IP 地址的详细编码与 CIDR 计算
|
||||
- [[hhs/NETWORK/TCP状态机详解]] — 四元组如何唯一标识 TCP 连接
|
||||
@@ -0,0 +1,165 @@
|
||||
---
|
||||
tags: [计算机网络, 带宽, 延迟, RTT, 吞吐量, BDP]
|
||||
create time: 2026-05-17 22:40
|
||||
---
|
||||
|
||||
# 带宽、延迟、RTT、吞吐量
|
||||
|
||||
## 概述
|
||||
|
||||
理解网络性能的核心指标,是优化应用的前提。带宽决定"管道有多粗",延迟决定"跑一程要多久",RTT 是往返一次的时间,而吞吐量是实际能搬多少数据。它们之间的关系经常影响系统架构设计。
|
||||
|
||||
## 核心定义
|
||||
|
||||
### 带宽(Bandwidth)
|
||||
|
||||
单位时间内能传输的**最大比特数**,通常用 bps(bits per second)表示:
|
||||
|
||||
```
|
||||
1 Gbps = 10⁹ bits/s = 125 MB/s(注意:bit vs Byte)
|
||||
```
|
||||
|
||||
| 链路类型 | 理论带宽 | 实际可用 |
|
||||
|----------|---------|---------|
|
||||
| 千兆以太网 (GbE) | 1 Gbps | ~940 Mbps(协议开销) |
|
||||
| Wi-Fi 6 (802.11ax) | 9.6 Gbps | ~1.2–2 Gbps(理论峰值) |
|
||||
| SATA III | 6 Gbps | 600 MB/s 实际 |
|
||||
| PCIe 4.0 x16 | 32 Gbps | ~3.9 GB/s |
|
||||
|
||||
> [!tip] bit vs Byte:记住除 8
|
||||
> 运营商说的 "100M 宽带" 是 **100 Mbps**。换算成下载速度约 `100 ÷ 8 ≈ 12.5 MB/s`。
|
||||
|
||||
### 延迟(Latency / Propagation Delay)
|
||||
|
||||
信号从发送端传播到接收端所需的时间,仅取决于**物理距离和介质光速**:
|
||||
|
||||
$$\text{Prop. Delay} = \frac{\text{Distance}}{v}$$
|
||||
|
||||
其中 $v$ 是传播速度。光纤中光速约为 $2 \times 10^8$ m/s(真空中光速的 2/3)。
|
||||
|
||||
| 场景 | 典型延迟 |
|
||||
|------|---------|
|
||||
| 同机房内 | 0.1–1 ms |
|
||||
| 同城(同一城市数据中心) | 1–5 ms |
|
||||
| 跨省(国内) | 20–40 ms |
|
||||
| 跨洋(中美) | 80–150 ms |
|
||||
| 卫星轨道(LEO) | 20–40 ms |
|
||||
| TCP 握手 + TLS 1.3 | 1~2 RTT(额外 RTT × 加密计算时间) |
|
||||
|
||||
### RTT(Round-Trip Time)
|
||||
|
||||
从发送方发出数据包到收到确认应答的总时间。**RTT = 2 × 单向延迟 + 排队处理时间 + 传输时间**。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["t=0ms: 发送 SYN"] -->|"传播+路由器处理"| B["t=5ms: 到达服务端"]
|
||||
B -->|"处理+准备响应"| C["t=5.1ms: 服务端回发 SYN-ACK"]
|
||||
C -->|"传播+路由器处理"| D["t=10.2ms: 客户端收到 → RTT = 10.2ms"]
|
||||
|
||||
style A fill:#DDA0DD,color:#000
|
||||
style D fill:#98FB98,color:#000
|
||||
```
|
||||
|
||||
### 吞吐量(Throughput)
|
||||
|
||||
单位时间内**实际成功传输的数据量**,受限于最窄环节:
|
||||
|
||||
$$\text{Throughput} = \min(\text{带宽}, \text{拥塞窗口限制}, \text{应用处理能力})$$
|
||||
|
||||
实际吞吐量永远 ≤ 带宽。常见瓶颈:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["磁盘IO<br/>可能 < 网卡"] --> B["TCP收发缓冲区"]
|
||||
B --> C["网络带宽"]
|
||||
C --> D["对端带宽"]
|
||||
D --> E["对端CPU/应用"]
|
||||
|
||||
F["中间路由拥塞"] -.-> C
|
||||
G["丢包重传"] -.-> C
|
||||
|
||||
style C fill:#FFD700,color:#000
|
||||
style F fill:#FF6B6B,color:#fff
|
||||
style G fill:#FF6B6B,color:#fff
|
||||
```
|
||||
|
||||
> [!question] 为什么我的千兆网卡只跑到 100MB/s?
|
||||
> 因为千兆以太网理论上限是 `1Gbps ÷ 8 = 125MB/s`,去掉以太网帧头、IP 头、TCP 头等协议开销后,纯 Payload 大约 **94 MB/s**。如果还用了 HTTPS/TLS,CPU 加解密还会进一步限制吞吐量。
|
||||
|
||||
## 带宽时延积(BDP)
|
||||
|
||||
**BDP(Bandwidth-Delay Product)** 定义了链路上"在途"数据的最大量——这是维持满带宽所需的发送缓冲大小:
|
||||
|
||||
$$\text{BDP} = \text{Bandwidth} \times \text{RTT}$$
|
||||
|
||||
### 实际意义
|
||||
|
||||
假设带宽 1 Gbps,RTT = 100 ms:
|
||||
|
||||
$$\text{BDP} = 10^9 \text{ bps} \times 0.1s = 10^8 \text{ bits} = 12.5 \text{ MB}$$
|
||||
|
||||
这意味着:
|
||||
- TCP 发送窗口至少要有 **12.5 MB**,才能填满这条管道
|
||||
- 如果窗口太小,TCP 会频繁停下来等 ACK,吞吐量上不去
|
||||
- 这就是 Linux 的 `net.core.rmem_max` / `wmem_max` 要调大的原因
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Pipe["管道: 1Gbps, RTT=100ms<br/>BDP = 12.5MB"]
|
||||
|
||||
Small["发送窗口 1MB ❌<br/>只能填 8% 管道 → 吞吐量 ≈ 80Mbps"]
|
||||
Big["发送窗口 25MB ✅<br/>填满管道 → 吞吐量 ≈ 1Gbps"]
|
||||
|
||||
Pipe --> Small
|
||||
Pipe --> Big
|
||||
|
||||
style Small fill:#FF6B6B,color:#fff
|
||||
style Big fill:#98FB98,color:#000
|
||||
```
|
||||
|
||||
### 各场景 BDP 速查
|
||||
|
||||
| 链路 | 带宽 | RTT | BDP |
|
||||
|------|------|-----|-----|
|
||||
| 局域网 | 1 Gbps | 0.5 ms | 62.5 KB |
|
||||
| 同机房 | 10 Gbps | 1 ms | 1.25 MB |
|
||||
| 同省 | 1 Gbps | 20 ms | 2.5 MB |
|
||||
| 跨洋 | 100 Mbps | 150 ms | 1.875 MB |
|
||||
|
||||
## 延迟 vs 带宽的典型对比
|
||||
|
||||
| 场景 | 带宽瓶颈还是延迟瓶颈? | 说明 |
|
||||
|------|---------------------|------|
|
||||
| 大文件传输 | 带宽 | 传输时间长,RTT 占比小 |
|
||||
| 小请求/高频交互(RPC) | 延迟 | 每个请求 2~3 RTT,带宽几乎不占 |
|
||||
| 视频流 | 带宽 | 持续大量数据传输 |
|
||||
| DNS 查询 | 延迟 | 单次查询仅几十字节 |
|
||||
| Web 首屏加载 | 两者兼有 | TCP+TLS握手(延迟)+ HTML/CSS/JS 下载(带宽) |
|
||||
|
||||
## Go 中的实践示例
|
||||
|
||||
```go
|
||||
// 设置 TCP 连接保持活跃,定期检测死链接
|
||||
tcp := net.ListenConfig{
|
||||
Control: func(network, address string, c syscall.RawConn) error {
|
||||
return c.Control(func() {
|
||||
// 开启 keepalive,每 30s 探测一次
|
||||
syscall.SetsockoptInt(int(c.Fd()), syscall.SOL_SOCKET,
|
||||
syscall.SO_KEEPALIVE, 1)
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
// HTTP Transport 的连接池配置
|
||||
transport := &http.Transport{
|
||||
MaxIdleConns: 100, // 最多空闲连接数
|
||||
MaxIdleConnsPerHost: 10, // 每个 host 最多 10 个空闲
|
||||
IdleConnTimeout: 90 * time.Second, // 空闲超时释放
|
||||
}
|
||||
```
|
||||
|
||||
## 关联笔记
|
||||
|
||||
- [[hhs/NETWORK/OSI与TCP-IP模型对比]] — 网络分层中各层的角色
|
||||
- [[hhs/NETWORK/TCP状态机详解]] — TCP 的拥塞控制直接影响吞吐量
|
||||
- [[hhs/NETWORK/TCP内核参数调优]] — BDP 对应内核参数 rmem/wmem
|
||||
Reference in New Issue
Block a user