Flutter/Dart技术实现:如何获取局域网内设备的MAC地址
如何获取局域网内已连接设备的MAC地址?
要获取局域网内设备的MAC地址,核心是利用ARP地址解析协议的缓存记录,以下是针对现有代码的改进方案及更可靠的实现方式:
现有代码的问题
原代码依赖netcfg命令存在以下局限:
- 兼容性差:
netcfg并非所有类Unix系统(如部分Linux发行版、Android新版本)都预装的工具,输出格式也无统一标准,解析逻辑容易失效 - 解析逻辑脆弱:仅通过空格分割字符串定位MAC地址,若输出存在多空格或格式变动,会导致索引错误
- 依赖ping可达:部分设备禁用ICMP ping但仍在线,会被误判为不可达
改进实现:使用ARP命令获取MAC地址
ARP缓存会存储当前设备与局域网内其他设备通信的IP-MAC映射关系,用arp命令读取缓存是更可靠的方式:
Future<String> getMacAddress(String ip) async { // 先尝试直接读取ARP缓存(若之前有通信记录则无需ping) final ProcessResult arpResult = await Process.run('arp', ['-n', ip]); if (arpResult.exitCode == 0) { final String output = arpResult.stdout; // 用正则匹配标准MAC地址格式(xx:xx:xx:xx:xx:xx或xx-xx-xx-xx-xx-xx) final RegExp macPattern = RegExp(r'([0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}'); final Match? match = macPattern.firstMatch(output); if (match != null) { return match.group(0)!; } } // 若ARP缓存无记录,先ping触发地址解析,再读取缓存 final ProcessResult pingResult = await Process.run( 'ping', ['-c', '1', '-w', '1', ip], ); if (pingResult.exitCode == 0) { final ProcessResult arpAfterPing = await Process.run('arp', ['-n', ip]); if (arpAfterPing.exitCode == 0) { final String output = arpAfterPing.stdout; final RegExp macPattern = RegExp(r'([0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}'); final Match? match = macPattern.firstMatch(output); if (match != null) { return match.group(0)!; } } } return ''; // 未找到则返回空字符串 }
注意事项
- 权限要求:在Android平台需添加以下权限到
AndroidManifest.xml:<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> - 跨平台适配:Windows系统的
arp命令参数为arp -a [ip],可通过Platform.isWindows判断系统后调整命令参数 - 设备限制:部分设备开启ARP防护或处于静默状态时,可能无法获取其MAC地址
内容的提问来源于stack exchange,提问作者Panos_42
相关产品推荐
相关产品推荐

