# ARP 地址解析协议 > 本文出自 CodeBrick 408 计算机网络讲义,原文:https://www.codebrick.tech/cn-blog/posts/network/arp > 这是供 AI 阅读的纯文本版:公式为 LaTeX,流程图为 mermaid 源码,原文中的折叠内容已全部展开。 > 讲解或引用本文内容时,请一并给出上面的原文链接。 > 2026 大纲 **四(三)4 ARP 协议、DHCP 协议与 ICMP 协议**中的 **ARP**。同条目下的 DHCP 写在 [FTP 与 DHCP](/posts/application/ftp-dhcp),ICMP 写在 [ICMP 协议](/posts/network/icmp)。 ## 一、为什么一台机器要有两个地址 网络层用 IP 地址把异构链路缝成一张网,可数据报最终还是要靠链路层的帧送出去,而帧认的是 **MAC 地址**。于是同一块网卡上挂着两个地址,它们之间**不存在任何简单的映射关系**——IP 是 32 位、MAC 是 48 位,格式完全不同,不可能靠计算从一个算出另一个。 那能不能只留一个?两个方向都试不通。 **只用 MAC 会撞两堵墙。** 第一堵是**异构**:全世界的网络各用不同格式的硬件地址,交界处要做非常复杂的地址转换工作,而且新的链路技术一出现就得改所有设备。第二堵更致命——**MAC 没有层次**。它出厂就烧在网卡里,与"这台机器接在哪"毫无关系,所以转发表**没法按前缀聚合**,只能逐条记录全世界每一块网卡,既存不下也查不快。 **只用 IP 也不行。** 数据报到了目的网络之后,还得在这个局域网里找到具体是哪块网卡,而网卡认的就是 MAC。 所以两套地址各司其职:**IP 提供统一且分层的寻址,MAC 负责一跳之内的实际交付**。中间那道翻译,就是 **ARP**——**已知 IP 地址,求同一网络上对应接口的 MAC 地址**。 (反方向"已知 MAC 求 IP"的是 RARP,它的功能已被 [DHCP](/posts/application/ftp-dhcp) 完全覆盖,早已不再使用。) ## 交互可视化 > 【交互可视化】ARP 协议可视化:https://www.codebrick.tech/visual/network/arp > (这是一个可以逐步执行的动画演示,纯文本版无法呈现,需要时请提示用户去这个链接看。) ## 二、同一网络内的解析:请求广播、响应单播 ```mermaid sequenceDiagram participant A as 主机A
192.168.1.10 participant NET as 本网络(广播域) participant B as 主机B
192.168.1.20 participant C as 主机C
192.168.1.30 A->>NET: ARP请求(广播)
"谁的IP是192.168.1.20?
顺带告诉你我是A/MAC-A" NET->>B: 收到,IP匹配 NET->>C: 收到,IP不匹配,丢弃 Note over B: 把A的IP-MAC写入自己的缓存 B-->>A: ARP响应(单播)
"我是192.168.1.20,MAC是MAC-B" Note over A: 把B的IP-MAC写入自己的缓存 ``` A 先查自己的 **ARP 高速缓存**,命中就直接用;未命中才广播。 **"请求广播、响应单播"不是随手规定的,是信息不对称的必然结果。** 请求时 A 手上只有 B 的 IP,帧的目的 MAC 字段**根本填不出来**,只能填广播地址让全网都收一遍;响应时 B 已经从请求分组里读到了 A 的 IP 和 MAC,完全可以精确地单播回去。 图里还有一个容易被略过的动作:**B 在回应之前先把 A 缓存了**。这是因为 **ARP 请求分组主动携带了发送方自身的映射**。这不是可有可无的优化——它让"收到请求的一方顺手就把请求方记下来"成为可能,**把一去一回的 ARP 开销直接减半**,后面的走查会具体数给你看。 关于 ARP 报文本身还有两条要记准。**它不封装在 IP 数据报里**,而是直接封装在链路层帧中(以太网帧类型字段 `0x0806`)——[ICMP](/posts/network/icmp)、IGMP 正好相反,都封装在 IP 数据报的数据部分里。**它也不能跨路由器工作**:请求是广播帧,而路由器隔离广播域,所以 **ARP 的作用范围严格等于一个广播域**(一个网络 / 一个 VLAN)。 最后这条正是下一节的根本原因。 ## 三、跨网络时:解析的是网关,不是目的主机 ```mermaid sequenceDiagram participant A as 主机A
192.168.1.10 participant R as 路由器
192.168.1.1 participant D as 主机D
192.168.2.50 Note over A: 与掩码相与,判定目的不在本网络 A->>R: ARP请求(广播)"谁的IP是192.168.1.1?" R-->>A: ARP响应(单播,网关MAC) A->>R: 数据帧(目的MAC=网关MAC,目的IP=D的IP) Note over R: 查转发表,得下一跳;再对下一跳做ARP R->>D: 数据帧(目的MAC=D的MAC,目的IP=D的IP) ``` A 判出目的不在本网络后,**不会**去广播找 D 的 MAC——广播帧根本出不了本网络。它要的是**网关的 MAC**。 **要害在于:A 封装的帧里目的 MAC 是网关的,而 IP 数据报里的目的 IP 仍然是 D 的。** 这两个字段属于两个不同的层,各管各的事——**MAC 管"这一跳送到谁手上",IP 管"最终送到哪"**。 推广开来就是本篇最重要的一句:**ARP 解析的永远是"下一跳"的 MAC,不是"最终目的"的 MAC。** 只有当下一跳恰好就是最终目的时,两者才重合。 四种典型情形不过是这一句话的四种落地: | 情形 | 发送方 | 目的主机的位置 | ARP 要解析的是谁的 MAC | |---|---|---|---| | ① | 主机 | **同一网络**上的另一台主机 | **目的主机**自己 | | ② | 主机 | 另一个网络上的主机 | 本网络上那台**路由器**(默认网关)的接口 | | ③ | 路由器 | 与本路由器**同一网络**上的主机 | **目的主机**自己 | | ④ | 路由器 | 还要再经过下一个路由器 | **下一跳路由器**的接口 | 再复杂的拓扑也只是这四种的反复使用。由此还能推出一个计数规律:**跨 $n$ 台路由器就是 $n+1$ 跳,冷缓存下需要 $n+1$ 次 ARP**。 配套还有一条常被忽视的事实:**路由器每个接口各有自己的 IP 和 MAC**,因为每个接口分属不同的网络。把路由器当成"一个 MAC 地址",逐跳表会全填错。 **〔原文中此段为可折叠内容〕跨两台路由器的逐跳地址与 ARP 次数走查,含回程为什么一次都不用(想把"IP 不变、MAC 逐跳变"落到每个字段上时展开)** 拓扑 `H1 ── N1 ── R1 ── N2 ── R2 ── N3 ── H2`,所有设备的 ARP 缓存初始为空。 | 设备接口 | IP 地址 | MAC 地址 | |---|---|---| | H1 | 192.168.1.10 | MAC-H1 | | R1 接 N1 的接口 | 192.168.1.1 | MAC-R1a | | R1 接 N2 的接口 | 10.0.0.1 | MAC-R1b | | R2 接 N2 的接口 | 10.0.0.2 | MAC-R2a | | R2 接 N3 的接口 | 172.16.5.1 | MAC-R2b | | H2 | 172.16.5.20 | MAC-H2 | **第 1 步:先数跳数。** ARP 是逐跳协议,每一跳的发送方都要先知道本跳接收方的 MAC,所以**跳数决定了 ARP 次数的上限**。数据报要过 N1、N2、N3 三条链路,即 **3 跳**。 **第 2 步:逐跳判断"这一跳的发送方需要谁的 MAC"**,套四种情形表: | 第几跳 | 发送方 | 情形 | 需要解析的 MAC | 是否已在缓存 | |---|---|---|---|---| | 1(N1) | H1 | ②(目的不在本网络) | R1 的 N1 接口(192.168.1.1) | 空 → **需 ARP** | | 2(N2) | R1 | ④(还要经下一个路由器) | R2 的 N2 接口(10.0.0.2) | 空 → **需 ARP** | | 3(N3) | R2 | ③(目的在本网络) | H2(172.16.5.20) | 空 → **需 ARP** | 去程共 **3 次 ARP**。 **第 3 步:逐条链路填四个地址。** | 链路 | 帧·源 MAC | 帧·目的 MAC | 数据报·源 IP | 数据报·目的 IP | |---|---|---|---|---| | N1 | MAC-H1 | **MAC-R1a** | 192.168.1.10 | 172.16.5.20 | | N2 | **MAC-R1b** | **MAC-R2a** | 192.168.1.10 | 172.16.5.20 | | N3 | **MAC-R2b** | **MAC-H2** | 192.168.1.10 | 172.16.5.20 | **右边两列一个字都没变,左边两列每一行全变。** 两处细节:R1 在 N1 上用 MAC-R1a、在 N2 上用 MAC-R1b,**一台路由器每个接口都有独立的 MAC 与 IP**;每一跳的源/目的 MAC 都是"本跳收发双方在本网络上那个接口的 MAC"——**MAC 地址对从来不跨网络**。 **第 4 步:回程为什么 0 次 ARP。** 去程三次 ARP 请求,每次都带着请求方自己的映射,收到请求的一方顺手缓存: | 第几跳 | 发送方 | 需要解析 | 缓存里有吗 | |---|---|---|---| | 1(N3) | H2 | R2 的 N3 接口 | **有**(去程 R2 的 ARP 请求带来的) | | 2(N2) | R2 | R1 的 N2 接口 | **有**(去程 R1 的 ARP 请求带来的) | | 3(N1) | R1 | H1 | **有**(去程 H1 的 ARP 请求带来的) | 去程的三次请求恰好把回程所需的三条映射全部"顺路"装进了对方的缓存,一去一回的开销从 6 次压到 3 次。**若题面明确规定"ARP 请求不携带发送方映射"或"只有响应方写缓存",则回程仍需 3 次、合计 6 次——先看清给定的口径。** ## 四、ARP 高速缓存与它的两个软肋 | IP 地址 | MAC 地址 | 类型 | 剩余有效期 | |---------|----------|------|--------| | 192.168.1.1 | MAC-R1a | 动态 | 2 分钟 | | 192.168.1.20 | MAC-B | 动态 | 12 分钟 | | 192.168.1.99 | MAC-X | **静态** | 永不过期 | **动态条目**由 ARP 学到,有生存时间(常见 2\~20 分钟),到期自动删除;**静态条目**由管理员手工配置,不会过期。 **为什么必须设有效期?** 因为 **ARP 没有任何"通知对方映射已失效"的机制**——换网卡、IP 回收后重新分配,都会让旧映射失效,而链路层不会告诉发送方"没人收"。**过期是唯一的自愈手段。** 有效期取多长是个折中:太长则故障恢复慢,太短则广播泛滥(广播域内每一台主机都要收下处理,代价按主机数放大)。 另一个软肋是安全:**协议没有任何认证机制**,任何主机都可以伪造 ARP 响应,声称"网关 IP 对应我的 MAC",形成中间人攻击(**ARP 欺骗**)。这是设计年代假设"局域网内所有站都可信"留下的产物。 顺带说明 ARP 的层次归属:它是与 IP 配套使用的三个协议之一(另两个是 [ICMP](/posts/network/icmp) 与 IGMP,见 [IP 多播](/posts/network/multicast))。有的教材因它服务于链路层封装而说它"跨越网络层与数据链路层",按谢希仁的口径它属于**网际层**。 ## 本节小结 1. **两套地址是必需的**:只用 MAC 撞上"异构网络地址格式不统一"和"MAC 无层次导致转发表压不下去"两堵墙,只用 IP 又无法在局域网内定位到具体网卡。IP 提供统一且分层的寻址,MAC 负责一跳内的实际交付,ARP 在每段链路的两端做翻译。 2. **请求广播 / 响应单播的不对称来自信息不对称**;而请求分组主动携带发送方自身映射,让"收到请求的一方顺手缓存请求方"成为可能,一去一回的 ARP 开销因此减半。 3. **ARP 解析的永远是下一跳的 MAC**,四种典型情形是同一条规则的四种落地;跨 $n$ 台路由器即 $n+1$ 跳、冷缓存下 $n+1$ 次 ARP,每条链路上源/目的 MAC 全变而源/目的 IP 一个字不动。缓存必须有有效期——ARP 没有撤销机制,过期是唯一的自愈手段。 ## 考点速记 ARP 在真题里被考过的形式有两种:**一种直接问它是干什么的,另一种给一张拓扑问"某个帧的目的 MAC 是什么"。第二种才是真正的考法。** **① ARP 协议的功能是什么**(cn-2012-38)。四个选项分别是"根据 IP 查 MAC""根据 MAC 查 IP""根据域名查 IP""根据 IP 查域名",答 **A**。后两个是 DNS 的正反两向,B 是已被淘汰的 RARP。**这道题唯一的价值是把四个方向摆在一起让你别记串。** **② 主机访问 Internet 时,第一个帧和后续帧的目的 MAC 分别是什么**(cn-2015-47 的第 (2) 问,整题 9 分)。主机 2 的 ARP 表为空,要访问 Internet,问它发出的**第一个**以太网帧的目的 MAC,以及封装真正 IP 分组的以太网帧的目的 MAC。 **两问的答案完全不同,这正是出题点。** 目的地在 Internet 上、不在本子网内 → 下一跳是默认网关,所以最终要用的是**路由器的 MAC**;可主机 2 现在还不知道路由器的 MAC,得先发 ARP 请求去问,而 **ARP 请求是广播**——所以**第一个帧的目的 MAC 是 FF-FF-FF-FF-FF-FF**。等 ARP 响应回来,主机 2 才发出真正的数据帧,**它的目的 MAC 是路由器的 00-a1-a1-a1-a1-a1**。 **别答成 Internet 上那台目的主机的 MAC**——跨网段时主机既不知道远端的 MAC,也不该用它。IP 分组的目的 IP 始终是最终目的,但链路层的目的 MAC 只是下一跳。 这道题的另外两问顺带把同条大纲的其余部分考了:第 (1) 问算 DHCP 可分配的地址范围(子网内 .1\~.254 扣掉 4 个静态地址 → **111.123.15.5 \~ 111.123.15.254**),并问 DHCP Discover 的源 IP 与目的 IP(**0.0.0.0 与 255.255.255.255**——客户端此时既没有 IP、也不知道子网号,只能用受限广播)。第 (3) 问是一道排错题:主机 1 的默认网关被配成了 DHCP 服务器的地址,**同子网的 WWW 服务器照样访问得到**(同网段直接 ARP 直送,不走网关),**但访问不了 Internet**(分组交给了 DHCP 服务器,而它不是路由器、没开 IP 转发,只会丢弃)。 **本篇练习区里还会出现另外五道题**:cn-2011-47 与 cn-2017-36 讲在 [IPv4 数据报格式](/posts/network/ip-datagram)(前者的第 (2) 问也考 ARP 请求的广播目的 MAC,判据与本篇完全一致);cn-2010-36 与 cn-2012-33 讲在 [ICMP 协议](/posts/network/icmp);cn-2025-36 考 DHCP REQUEST 报文的源/目的 IP,讲在 [FTP 与 DHCP](/posts/application/ftp-dhcp)。 > **易错**:**ARP 解析的是下一跳的 MAC,不是最终目的的 MAC。** 跨网段时要的是网关的 MAC。 > **易错**:**ARP 表为空时发出的第一个帧是 ARP 请求,目的 MAC 是全 F 广播**;数据帧是第二个才发出去的。 > **易错**:**帧的目的 MAC 逐跳都换,IP 数据报的目的 IP 从头到尾不变。** 这是两个层的两件事。 > **易错**:**路由器每个接口各有独立的 IP 和 MAC。** 逐跳填表时别当成一个地址。 > **易错**:**ARP 请求是广播,出不了本广播域**,所以 ARP 不能跨路由器工作。 > **易错**:**ARP 报文直接封装在链路层帧里(类型 `0x0806`)**,不封装在 IP 数据报中;ICMP 与 IGMP 正好相反。 > **易错**:**ARP 请求携带发送方自身的映射**,所以对方顺手就缓存了请求方——数 ARP 次数时这一条会让回程降到 0 次。但题面另有规定时以题面为准。 > **易错**:**默认网关配错只影响跨子网通信**,同子网直接 ARP 直送照样通。 **〔原文中此段为可折叠内容〕教材出处** - 谢希仁《计算机网络》(第 8 版):ARP 的定位,见印刷版 **p119**(4.2 网际协议 IP)——"与协议 IP 配套使用的还有三个协议:地址解析协议 ARP、网际控制报文协议 ICMP、网际组管理协议 IGMP",其中"ARP 画在最下面,因为 IP 经常要使用这个协议"。同页说明 RARP"现在已被淘汰不使用了"。 - 同书 **p133**(4.2.4 地址解析协议 ARP):ARP 存在的理由——"IP 地址和下面链路层的 MAC 地址之间由于格式不同而不存在简单的映射关系(例如,IP 地址有 32 位,而链路层的 MAC 地址是 48 位)。此外,在一个网络上可能经常会有新的主机加入进来,或撤走一些主机。更换网络适配器也会使主机的 MAC 地址改变",解决办法是"在主机的 ARP 高速缓存中存放一个从 IP 地址到 MAC 地址的映射表,并且这个映射表还经常动态更新(新增或超时删除)";同页指出 DHCP"已经包含了协议 RARP 的功能"。 - 同书 **p134**:请求广播、响应单播——"虽然 ARP 请求分组是广播发送的,但 ARP 响应分组是普通的单播,即从一个源地址发送到一个目的地址";以及**回程省 ARP 的机制**:"主机 A 在发送其 ARP 请求分组时,就把自己的 IP 地址到 MAC 地址的映射写入 ARP 请求分组。当主机 B 收到 A 的 ARP 请求分组时,就把主机 A 的这一地址映射写入主机 B 自己的 ARP 高速缓存中。以后主机 B 向 A 发送数据报时就很方便了"。本篇走查第 4 步的结论即由此而来。 - 同书 **p135**:**缓存必须设有效期**的论证——教材举的例子是主机 B 更换网络适配器后 MAC 地址变化,"A 在其 ARP 高速缓存中查找到 B 原先的 MAC 地址,并使用该 MAC 地址向 B 发送数据帧。但 B 原先的 MAC 地址已经失效了,因此 A 无法找到主机 B。但是过了一段不长的生存时间,A 的 ARP 高速缓存中已经删除了 B 原先的 MAC 地址,于是 A 重新广播发送 ARP 请求分组,又找到了 B"。同页给出**使用 ARP 的四种典型情况**(图 4-19),本篇第三节那张表即依此重排。 - 同书 **p135–p136**:为什么不能只用 MAC 地址——"由于全世界存在着各式各样的网络,它们使用不同的 MAC 地址。要使这些异构网络能够互相通信就必须进行非常复杂的 MAC 地址转换工作……即使是对分布在全世界的以太网 MAC 地址进行寻址,也是极其困难的。然而 IP 编址把这个复杂问题解决了"。同书 **p141** 从转发表规模的角度补上另一半理由:"能不能在转发表中不使用 IP 地址而直接使用 MAC 地址呢?不行……在转发表中直接使用 MAC 地址,那就会带来更多的麻烦,甚至无法找到对方的机器"。 ## 相关知识 [IP 编址](/posts/network/ip-addressing)|[ICMP 协议](/posts/network/icmp)|[路由器与分组转发](/posts/network/router)|[以太网与 IEEE 802.3](/posts/datalink/ethernet)|[以太网交换机](/posts/datalink/switch-learning)|[NAT](/posts/network/nat) ## 真题练习 ## 本节对应的历年 408 真题 - 2010 年第 36 题:https://www.codebrick.tech/practice/q/cn-2010-36 - 2011 年第 47 题:https://www.codebrick.tech/practice/q/cn-2011-47 - 2012 年第 33 题:https://www.codebrick.tech/practice/q/cn-2012-33 - 2012 年第 38 题:https://www.codebrick.tech/practice/q/cn-2012-38 - 2015 年第 47 题:https://www.codebrick.tech/practice/q/cn-2015-47 - 2017 年第 36 题:https://www.codebrick.tech/practice/q/cn-2017-36 - 2025 年第 36 题:https://www.codebrick.tech/practice/q/cn-2025-36