You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 ''; // 未找到则返回空字符串
}

注意事项

  1. 权限要求:在Android平台需添加以下权限到AndroidManifest.xml:
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    
  2. 跨平台适配:Windows系统的arp命令参数为arp -a [ip],可通过Platform.isWindows判断系统后调整命令参数
  3. 设备限制:部分设备开启ARP防护或处于静默状态时,可能无法获取其MAC地址

内容的提问来源于stack exchange,提问作者Panos_42

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 20:35:26