220 lines
8.3 KiB
Markdown
220 lines
8.3 KiB
Markdown
---
|
||
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: 写入缓存条目 (Linux 默认 ≈ 30s, Windows ≈ 15~45s, 可配置)
|
||
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 | — | 支持无状态自动配置 |
|
||
| 组播 | 有限支持 | 原生支持 |
|
||
| 地址解析 | ARP(广播) | NDP / Neighbor Discovery(组播,替代 ARP) |
|
||
|
||
### IPv6 地址表示与压缩
|
||
|
||
IPv6 地址共 128 位,用冒号分隔为 8 组,每组 4 个十六进制数:
|
||
|
||
```
|
||
完整写法: 2001:0db8:0000:0000:0000:0000:0000:0001
|
||
压缩规则 1 — 每组前导零可省略: 2001:db8:0:0:0:0:0:1
|
||
压缩规则 2 — 连续全零组用 :: 替代(仅一次): 2001:db8::1
|
||
```
|
||
|
||
> [!QUESTION] `::` 能用几次?
|
||
> 只能用**一次**。如果出现两个 `::`,解析器无法确定每组省略了多少个零,地址就会歧义。
|
||
|
||
### IPv6 特殊地址
|
||
|
||
| 地址 | 用途 |
|
||
|------|------|
|
||
| `::1` | 环回地址,等价于 IPv4 的 `127.0.0.1` |
|
||
| `::` | 未指定地址,等价于 IPv4 的 `0.0.0.0` |
|
||
| `fe80::/10` | 链路本地地址(Link-Local),同一链路自动通信 |
|
||
| `ff00::/8` | 组播地址 |
|
||
|
||
> 更多 IPv6 细节见 [[hhs/NETWORK/03-网络层/03-IPv6地址与扩展头部]]。
|
||
|
||
### 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)。
|
||
> CIDR 用"前缀长度"取代了固定的 A/B/C 类划分,例如 `192.168.1.0/24` 表示前 24 位是网络号,剩余 8 位是主机号。
|
||
> 更多细节见 [[hhs/NETWORK/03-网络层/02-CIDR与子网划分]]。
|
||
|
||
### 特殊 IP 地址
|
||
|
||
| 地址 | 用途 |
|
||
|------|------|
|
||
| `127.0.0.1` / `::1` | 环回地址(Loopback),本机内部通信 |
|
||
| `0.0.0.0` | 表示"本机所有网卡"(服务端 bind 时常用) |
|
||
| `169.254.x.x` | 链路本地地址(DHCP 失败时自动分配) |
|
||
|
||
### 私有 IP 地址段
|
||
|
||
互联网上的路由器**不会转发**来自以下范围的数据包,它们仅用于内网,通过 NAT 转换为公网 IP 后才能访问互联网:
|
||
|
||
| 类别 | 地址范围 | CIDR | 可用地址数 |
|
||
|------|---------|------|-----------|
|
||
| A 类 | `10.0.0.0` ~ `10.255.255.255` | `10.0.0.0/8` | ~1677 万 |
|
||
| B 类 | `172.16.0.0` ~ `172.31.255.255` | `172.16.0.0/12` | ~104 万 |
|
||
| C 类 | `192.168.0.0` ~ `192.168.255.255` | `192.168.0.0/16` | ~6.5 万 |
|
||
|
||
> [!tip] 私有地址 + NAT = 解决 IPv4 耗尽
|
||
> 一个公网 IP 可以通过 NAT 映射背后成百上千个私有 IP,这就是为什么 IPv4 至今仍在大规模使用。详见 [[hhs/NETWORK/03-网络层/08-NAT原理与应用]]。
|
||
|
||
## 三、端口号(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)`
|
||
|
||
### 常见端口速查
|
||
|
||
| 端口 | 协议 | 服务 |
|
||
|------|------|------|
|
||
| 20 | FTP-Data | 文件传输数据通道 |
|
||
| 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/01-基础概念/01-OSI与TCP-IP模型对比]] — 三层地址对应 OSI 的不同层级
|
||
- [[hhs/NETWORK/03-网络层/01-IPv4首部与分段重组]] — IP 首部的详细字段与分段机制
|
||
- [[hhs/NETWORK/03-网络层/02-CIDR与子网划分]] — CIDR 计算与子网划分实战
|
||
- [[hhs/NETWORK/04-传输层/01-TCP段结构与状态机]] — 四元组如何唯一标识 TCP 连接
|