ARP 解决「知道 IP、不知道 MAC」:同一网段内发数据前必须先问出对方的硬件地址。 问的方式是广播,答的方式是单播,答完双方都缓存一份。
5.2 讲完了「名字变地址」,这一节讲「地址变 MAC」。 3.2.1 的 MAC 地址是它的目标,这一节是两者的连接点。
一、为什么需要它
因为链路层只认 MAC,不认 IP。 你的网卡发不出去「目的地是 192.168.3.1」这种话,它只会发「目的地是某个 MAC 的帧」。
| 层 | 认识什么 | 不认识什么 |
|---|---|---|
| IP 层 | IP 地址 | MAC |
| 链路层 | MAC 地址 | IP |
两行互相「不认识对方的名字」,所以中间必须有一个翻译。 ARP 就是这个翻译,而且它只在「同一网段内」工作—— 跨网段时问的是网关的 MAC,不是最终目的地的 MAC。 这一点最容易搞混:「ping 8.8.8.8」时,ARP 问的是网关的 MAC, 8.8.8.8 的 MAC 你永远不知道,也不需要知道。
二、四步走完
过程只有四步:
| 步 | 谁发 | 发什么 |
|---|---|---|
| 1 | 请求方 | 广播「谁是 192.168.3.1」 |
| 2 | 目标 | 单播「我是,我的 MAC 是 xx」 |
| 3 | 请求方 | 记进 ARP 表 |
| 4 | 双方 | 后续直接用 MAC 通信 |
第一步是广播,第二步是单播,这个不对称很关键: 「我不知道你是谁,所以只能喊」;「我知道你是谁,所以可以点名回」。 如果第二步也用广播,整个网段都要陪着听一遍,纯浪费。 第四步「双方都缓存」常被忽略:应答方也会把请求方的 IP-MAC 记下来, 因为「你既然要跟我说话,我大概也要回你」。 这个小优化让双向通信的第二次不用再广播。
三、表会长什么样
ARP 表就三列:IP、MAC、类型(动态或静态)。
| 类型 | 怎么来的 | 会过期吗 |
|---|---|---|
| 动态 | 广播学来的 | 会,一般 20 分钟 |
| 静态 | 手工写的 | 不会 |
第一行「20 分钟」不是随便定的:太短会让广播变多,太长会让「换了网卡还连旧地址」。 这个值是「广播开销」和「信息新鲜度」的折中。 第二行「静态」用来钉住关键设备:比如网关、打印机, 钉住之后即使它换了 IP 也能立刻通——代价是「换设备时要手动改」。
四、动手 Demo:本机 ARP 表里有什么
直接读本机的 ARP 表,看条目数、动态与静态的分布、MAC 的厂商前缀。 注意那几条静态记录其实是广播和多播地址。
import re, subprocess
out = subprocess.run('arp -a', shell=True,
capture_output=True).stdout.decode('gbk')
for ln in out.split('\n'):
m = re.match(r'\s*(\d+\.\d+\.\d+\.\d+)\s+(\S+)\s+(\S+)', ln)
if m:
print(m.group(1), m.group(2), m.group(3))
实跑输出:
--------------------------------------------------------------------
本机 ARP 表里有什么
--------------------------------------------------------------------
**ARP 表就是「IP 到 MAC 的最近答案」**:**同一网段通信前先查它,查不到才发广播。**
**本机 ARP 表共 9 条**:
IP 地址 MAC 地址 类型
-----------------------------------------------
192.168.3.1 b0-fe-e5-54-e9-3f 动态
192.168.3.74 4c-b7-e0-34-60-6c 动态
192.168.3.147 58-cd-c9-df-80-6e 动态
192.168.3.255 ff-ff-ff-ff-ff-ff 静态
224.0.0.22 01-00-5e-00-00-16 静态
224.0.0.251 01-00-5e-00-00-fb 静态
224.0.0.252 01-00-5e-00-00-fc 静态
239.255.255.250 01-00-5e-7f-ff-fa 静态
**其中动态 3 条、静态 6 条。**
**「动态」是靠广播学来的,会老化**;
**「静态」这几条其实是广播地址和多播地址**——**系统自动加的,不是人写的,所以也永不过期。**
**再看 MAC 的前三个字节**:**它是厂商编号(OUI),一台设备刚上线就能猜出是什么牌子。**
MAC OUI(前三字节)
--------------------------------------
B0:FE:E5:54:E9:3F B0:FE:E5
4C:B7:E0:34:60:6C 4C:B7:E0
58:CD:C9:DF:80:6E 58:CD:C9
FF:FF:FF:FF:FF:FF FF:FF:FF
01:00:5E:00:00:16 01:00:5E
01:00:5E:00:00:FB 01:00:5E
**这张表是排查「同网段不通」的第一现场**:
**如果网关那条不在表里,说明 ARP 都没成功**——**那问题就在链路层,不在 IP 层。**
表里那几条静态记录最容易让人困惑:192.168.3.255 是广播地址、224.0.0.x 是多播地址, 它们对应的 MAC 是「约定的固定值」(比如广播是 FF-FF-FF-FF-FF-FF)。 所以它们不是「学来的」,而是「算出来的」,类型标成静态。 MAC 的前三个字节是厂商编号(OUI):同一批设备往往前三个字节相同, 所以「这台设备是什么牌子」看 OUI 就能猜个大概。 这也是「为什么 MAC 不能随便改」的一个原因——改了会和别人的厂商标识撞车。 「网关那条在不在表里」是最好的排查起点: 不在,说明 ARP 没成功(链路或 VLAN 有问题);在了但 ping 不通,问题在 IP 层以上。 这一步就能把故障范围砍掉一半。
30 秒实验
- 想一下:为什么 ARP 请求用广播、应答用单播?
- 想一下:ping 8.8.8.8 时,ARP 问的是谁的 MAC?
- 算一下:一个 /24 网段最多有多少条动态 ARP 记录?
常见误区
- 以为「ARP 能跨网段工作」。 不能,广播出不了路由器,跨网段问的是网关。
- 以为「ARP 表是永久的」。 动态条目会老化,一般 20 分钟。
- 以为「知道了 IP 就能直接发帧」。 还要先有 MAC,这就是 ARP 的全部意义。
自测三问(点开对答案)
1. ARP 解决什么问题? —— **已知 IP 地址,求同一网段内的 MAC 地址**,因为链路层只认 MAC。 2. ARP 请求和应答分别怎么发? —— **请求广播、应答单播**,避免整个网段陪听。 3. ARP 表项一般多久过期? —— **动态条目约 20 分钟**,静态条目不过期。下一节把 ARP 的四步拆细,看它出问题时会怎样。
- ☐ (本节完,下一节 5.3.2 ARP的工作机制)