简介:这是一份面向Android开发者的ARP协议演示工程,旨在通过读取本地ARP表,获取当前局域网内其他设备的IP与MAC信息,适合需要实现局域网设备发现或MAC扫描功能的开发场景。资源包共25个文件,以4个Java源码文件为核心,配合6个XML布局与配置文件、10张PNG图片资源,以及Gradle构建脚本和说明文档;压缩包整体仅80KB,结构紧凑,便于直接导入Android Studio查看。目前已有884人学习使用。代码完整覆盖获取本机WiFi IP、根据IP地址发送ARP请求、读取本地ARP表三个关键步骤,能够帮助读者理解局域网设备发现原理,并掌握IP与MAC映射关系的实际读取方法。工程采用标准Android工程目录,初学者可结合源码与图片资源逐项分析,有经验的开发者也能直接提取ARP请求模块,快速集成到自有网络工具或物联网项目中。 开篇先说个事:我平时喜欢把网上下载的源码压缩包按名字归好类再统一解压,前几天翻硬盘时刚好看到一个叫ARPDemo-master.zip的压缩包,文件名很直白,就是一份 ARP 协议演示工程,从 Git 仓库下载的默认 master 分支打包版本。顺手解压跑了一遍,又把抓包、调试过程重新过了一次,收获比预期大不少。这篇文章就把这整套实践整理出来,从协议原理、项目结构到本地复现、常见坑点,一次说清楚。适合刚接触网络协议、想用真实代码加深理解的朋友,也适合准备做网络编程作业或遇到 ARP 缓存问题后想搞懂背后机制的开发者。
1. 为什么选这个项目来做协议实践
1.1 ARP 是网络通信里绕不开的“翻译官”
IP 地址用来标识主机在网络层的位置,但数据真正要在局域网里传输时,依赖的却是网卡上的 MAC 地址。ARP,全称 Address Resolution Protocol,就是负责把 IP 地址“翻译”成 MAC 地址的协议。可以把它理解成小区物业的联系方式簿:你只知道张三住在几栋几单元,但想按门铃,还得从物业那里查到他的门牌号。任何一台主机要往局域网里另一台机器发包,第一步基本都得走 ARP 流程,除非目标 MAC 已在缓存中。
这个协议足够简单,报文也很短,非常适合初学者手写、抓包、验证。不像 TCP 那样有繁琐的状态机,也不像 DNS 那样需要区分递归、迭代、缓存过期策略。只要会看 28 字节的 ARP 报文,再配合 Pcap、Scapy 这类库,就能做出可玩性很高的 Demo。ARPDemo这类项目往往就围绕“构造请求、接收应答、解析字段”三个动作展开。
1.2 master 分支打包带来的项目结构
从 GitHub 下载的仓库默认分支通常是 master 或 main,ARPDemo-master.zip就是仓库 master 分支打包后的文件。解压后一般能看到README.md、src/、requirements.txt、config.ini之类的标准文件。以我常用的一个 Python 版本 ARP Demo 为例,目录通常是:
ARPDemo-master/ ├── README.md ├── requirements.txt ├── config.ini ├── main.py ├── arp_client.py ├── arp_server.py └── utils/ └── packet.pyarp_client.py负责构造 ARP 请求,arp_server.py负责监听并回包,utils/packet.py是报文解析与封装工具。有些版本会做成命令行工具,支持发送自定义 IP 的 ARP 请求、查看网卡列表、输出十六进制报文等功能。先跑通这样一个项目,相当于把协议的学习从“背报文格式”升级成了“写代码还原协议”。
2. 核心技术点拆解:从以太网帧到 ARP 报文
2.1 ARP 报文结构到底长什么样
ARP 报文本身不长,固定字段加可变填充一共 28 字节。如果要做项目复现,这几个字段必须搞清楚。我整理了一个常用对照表,方便边看代码边比对:
| 字段 | 长度 | 含义 | 常见值 |
|---|---|---|---|
| 硬件类型 | 2 字节 | 链路层类型 | 1 表示以太网 |
| 协议类型 | 2 字节 | 网络层协议 | 0x0800 表示 IPv4 |
| 硬件地址长度 | 1 字节 | MAC 地址字节数 | 6 |
| 协议地址长度 | 1 字节 | IP 地址字节数 | 4 |
| 操作码 | 2 字节 | 1 为请求,2 为应答 | 1 / 2 |
| 发送方 MAC | 6 字节 | 请求方或应答方 MAC | 网卡真实 MAC |
| 发送方 IP | 4 字节 | 请求方或应答方 IP | 如 192.168.1.100 |
| 目标 MAC | 6 字节 | 请求时通常填 00:00:00:00:00:00 | 全 0 |
| 目标 IP | 4 字节 | 要解析的 IP | 如 192.168.1.1 |
以太网帧头部还需要额外 14 字节:目标 MAC 6 字节、源 MAC 6 字节、类型字段 2 字节(ARP 是 0x0806)。抓包时如果看到 42 字节左右的数据包,往往就是在 28 字节 ARP 报文基础上填充到以太网最小帧长度 46 字节,再加上 4 字节 FCS 校验,最终线上数据可能是 60 字节或更多。
在做 Demo 时,最容易出错的就是操作码和地址长度写反。我见过不少把硬件地址长度写成 4、协议地址长度写成 6 的代码,这种包发出去,网卡能收但上层解析全乱。写代码前先把结构体画出来,对着操作码逐一赋值,稳妥很多。
2.2 用抓包验证协议交互过程
跑 ARP Demo 时一定要配合 Wireshark 或 tcpdump 验证,别只盯着终端输出。终端上打印“sent 1 packet”只能说明包发出去了,不能说明格式对、方向对。实际操作时,可以在本机开两个终端,先启动监听模式,再向一个目标 IP 发起 ARP 请求,同时抓包观察。
以 Wireshark 为例,抓包过滤条件可以直接写arp,这样把其他网络流量都屏蔽掉。正常情况下你会看到两条核心报文:
第一是 ARP 请求,操作码为 1,目标 MAC 全零,目标 IP 是你要查询的地址; 第二是 ARP 应答,操作码为 2,发送方 MAC 变成了目标主机的 MAC,目标 MAC 则是请求方的 MAC。
这里有个实战经验:如果你的 Demo 能发出请求,但收不到应答,先不要怀疑程序,先用ping -c 1 目标IP通一下网络,再用系统自带的arp -a看缓存里有没有记录。如果系统能解析而你的程序不能,问题多半出在网卡绑定、包格式或抓包设备选择上。反之,如果系统也解析不了,那目标 IP 可能根本不通,或者被防火墙拦截了 ARP 报文。
3. 实操过程:在本地把 ARPDemo 跑起来
3.1 环境准备与依赖安装
ARPDemo如果是 Python 项目,依赖相对简单。我这里是基于 Scapy 2.5.0 版本跑的。Scapy 是一个很出名的 Python 网络包构造与解析库,能直接操作链路层,特别适合 ARP 这类底层协议的实验。
安装环境时可以按下面步骤来:
# 建议用虚拟环境,避免污染系统 Python python -m venv arp-env source arp-env/bin/activate # Windows 下执行 arp-env\Scripts\activate pip install scapy pip install -r requirements.txt注意,Windows 上发送原始包通常需要 Npcap 或 WinPcap 驱动,Scapy 底层会调用这些驱动。如果安装后运行报“No such device exists”或“cannot open device”,先去装 Npcap 而不是 WinPcap,WinPcap 已经停止维护,现代 Windows 系统兼容性差。Linux 则一般需要 libpcap 开发包,而且发送原始以太网帧必须用 root 或 sudo 权限。
3.2 修改配置与启动测试
很多 ARP Demo 项目会提供一个config.ini,里面记录网卡名称、目标 IP、发送次数、间隔时间。我第一次跑的时候直接用了默认配置,结果发送到网卡后根本没反应,因为默认网卡名和本机实际网卡名对不上。
这时可以先跑一段网卡探测代码,把系统中所有可用网卡列出来:
from scapy.all import get_if_list, get_if_addr for iface in get_if_list(): print(iface, get_if_addr(iface))在 Linux 上,输出结果一般有lo、eth0、wlan0这类名字;Windows 上则是Intel(R) Ethernet Connection …这种长名字。把输出里的实际网卡名填回config.ini的interface字段。然后运行主程序,向本机网关发起一次 ARP 请求,比如网关是192.168.31.1,命令大致是:
python main.py --iface eth0 --ip 192.168.31.1 --count 1正常输出的关键信息包括发送方 MAC、目标 IP 和收到的应答 MAC。如果目标 IP 可达,应该会看到类似这样的一行:
ARPScan: 192.168.31.1 is reachable, MAC=XX:XX:XX:XX:XX:XX如果目标不可达,很多 Demo 也会给出“no response”的提示。这种反馈很适合拿来验证协议超时机制。
3.3 Demo 代码里的核心逻辑与改造点
跑通之后,我通常会建议去看项目里的封包函数。以 Scapy 为例,构造一个 ARP 请求只需要几行:
from scapy.all import ARP, Ether, srp pkt = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst="192.168.31.1") ans, _ = srp(pkt, timeout=3, verbose=0) for sent, received in ans: print(received[ARP].hwsrc)这里Ether(dst="ff:ff:ff:ff:ff:ff")的作用是让请求以广播形式发出去,ARP(pdst="...")指定要解析的 IP。函数srp会同时发送第二层以太网帧并接收应答。整个协议的核心其实就是这段代码,其余工作基本都花在界面、日志和异常处理上。
如果想让 Demo 更接近生产场景,可以改造两点:
一是增加 ARP 缓存合并逻辑,把收到的多个应答按源 IP 去重,只保留最后一个; 二是增加超时重传,比如连续发 3 次,每次间隔 1 秒,避免单次丢失导致误判。
3.4 常见报错排查实录
跑这类项目时,我踩过不少坑,这里整理成表格,方便大家对照:
| 报错现象 | 可能原因 | 解决建议 |
|---|---|---|
Permission denied | 发送原始套接字需要权限 | Linux 下加 sudo,Windows 下确认以管理员运行终端 |
Cannot open device | Scapy 找不到网卡 | 先用get_if_list()确认网卡名,不要凭经验输入 |
| 能发请求但收不到应答 | 防火墙拦 ARP | 检查系统防火墙,或先在纯局域网虚拟机内测试 |
解析结果全为ff:ff:ff:ff:ff:ff | 封包时目标 MAC 设置错误 | 确认请求包的目标 MAC 是全 0,而不是全 f |
| Windows 下运行卡住 | Npcap 驱动未安装 | 去 Npcap 官网下载安装,装完重启终端 |
这些错误里,权限问题出现频率最高,尤其是新手在 Linux 命令行上忘了sudo。其实 Scapy 这类库因为要直接操作链路层,几乎绕不开管理员权限,这不是项目本身的问题。
4. 从 Demo 到实战:应用场景与避坑清单
4.1 用 ARP Demo 做网络故障判断
很多入门教程只把 ARP Demo 当成一次抓包练习,其实它在实际网络排障里特别有用。比如你怀疑某台设备的 IP 和 MAC 绑定关系异常,就可以用类似 Demo 里的单次请求功能,快速拿到目标 IP 对应的 MAC,再用arp -a对比本机缓存,能立刻发现是否被其他设备占用。
我曾在办公网里排查过一台打印机频繁掉线的问题,打印一个 IP 的 ARP 请求后,发现返回的 MAC 居然指向一台网络摄像头。顺着 MAC 找到设备,原来是摄像头被人手动配了打印机同款 IP。这种问题用普通 ping 测不出来,因为 ICMP 包还能通,但上层打印协议走到一半就断了。ARP 请求能第一时间暴露 IP-MAC 映射异常。
如果要在多个网段做扫描,先把 Demo 改成批量模式,对一个网段内所有 IP 发起请求,就能得到一张存活设备与 MAC 映射表,这对做资产盘点也有参考价值。
4.2 安全视角:理解协议机制,更要懂得防御
ARPDemo 这类项目最常见的延展方向是协议安全测试。但这里必须提醒一点:理解协议机制是为了更好地防御,不是为了让实验环境成为攻击工具。ARP 是一个没有任何认证机制的协议,局域网内任何主机都可以发送伪造的应答,宣称“某个 IP 的 MAC 是我”,这就会导致正常通信被误导到错误设备上。
防御层面,比较有效的措施包括:
- 在交换机上配置 DHCP Snooping,只信任来自合法 DHCP 服务器的报文;
- 启用动态 ARP 检测,让设备对收到的 ARP 报文进行合法性校验;
- 对关键设备设置静态 ARP 表,比如在网关、服务器上手动绑定 IP 和 MAC;
- 定期用类似 Demo 的扫描工具对比局域网内 IP-MAC 映射,发现异常及时排查。
我在自己电脑上做实验时也会顺手写一个定时监控脚本:每天扫描一次网关 MAC,如果发现和前一天的记录不一致,就直接告警。这种做法成本低,效果却很直接。
4.3 给后来者的几条实操建议
第一,实验环境尽量用虚拟机加虚拟网络。VirtualBox 或 VMware 里建两台虚拟机,网络模式选“仅主机模式”,就能得到一个隔离的局域网,想发多少 ARP 包都不会影响家里其他设备,也更安全。
第二,抓包不要开着其他流量。跑 ARP 实验时,本机如果同时在联网更新、播放视频,抓包里会混入大量无关 ARP 广播,干扰判断。建议先把浏览器和后台应用关掉,过滤条件写死arp。
第三,别只跑通就不管了。我会建议你把项目里的单次请求改成循环扫描,再加一个状态实时打印,这样对协议的理解能深一层。改代码的过程往往比运行代码更能暴露知识盲区,比如你会注意到广播风暴、响应时间、丢包重传这些问题,都是 Scapy 默认帮你隐藏掉的核心细节。
我自己在跑这个 ARP Demo 时最大的体会是:越是看似简单的协议,越能练基本功。ARP 只有寥寥几个字段,但把它真正跑通、抓到包、解析每个字节,比看十遍协议文档都管用。后面如果你感兴趣,还可以在这个 Demo 基础上加入静态 ARP 绑定、ARP 缓存老化模拟、跨网段请求时的网关代理解析等功能,每一块都值得单独写一篇笔记慢慢研究。
本文还有配套的精品资源,点击获取