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

Flutter如何扫描局域网设备 获取IP、MAC地址及设备类型信息

局域网设备列表功能完整实现路线

整个功能分三个核心环节实现,不需要依赖额外重型SDK,各环节逻辑解耦方便调试:

1. 存活IP采集

你目前用的lan_scanner已经可以覆盖这部分需求,核心逻辑是遍历当前网段的所有IP,通过ICMP ping或者常用端口探测筛选出在线设备。

  • 扫描前不要硬编码网段,先获取本机IP地址,比如本机IP是192.168.1.12,就自动生成192.168.1.1-192.168.1.254的扫描范围,适配不同的局域网网段配置。
  • 扫描并发数建议控制在10-15,过高会触发系统网络限制,也可能影响局域网内其他设备的网络使用。

2. IP对应MAC地址获取

这部分没有通用跨平台库可以直接用,基于ARP协议实现即可,同网段下准确率接近100%:

  • 移动端(Android/iOS):主动给存活IP发送ARP请求,或者直接读取系统本地的ARP缓存表,解析出IP和MAC的映射关系。注意Android需要声明ACCESS_WIFI_STATE权限,iOS 14及以上版本需要申请本地网络权限,否则ARP请求会被系统拦截。
  • 桌面端(Windows/macOS/Linux):直接调用系统自带的ARP查询命令,用正则匹配返回结果里的IP、MAC字段即可,不需要额外构造网络包。

注意:跨三层交换机、跨VLAN的设备无法通过ARP拿到MAC地址,普通家用路由器下的局域网不存在这个问题。

3. 设备类型识别

这部分用「OUI粗筛 + mDNS精细识别」的组合方案,识别准确率最高:

  • OUI粗筛:MAC地址的前3个字节是厂商统一分配的OUI标识,提前维护一份公开的OUI和设备类型的映射表,比如打印厂商的OUI对应打印机、手机厂商的OUI对应移动设备、网卡厂商的OUI对应PC,先给每个设备打初始标签。
  • mDNS精细识别:你调研的multicast_dns库就是用来做这部分的,大部分手机、PC、智能硬件、打印机默认都会开启mDNS服务广播自身信息:
    1. 启动mDNS客户端后,先发送_services._dns-sd._udp.local的指针查询,拿到局域网内所有广播的服务类型
    2. 针对每个服务类型,进一步查询对应的SRV记录和A记录,拿到设备的IP、端口、设备名信息
    3. 根据服务类型判断设备类别:
    • 返回_ipp._tcp/_printer._tcp服务的是打印机
    • 返回_airplay._tcp服务的是苹果系智能设备
    • 返回_smb._tcp服务的大概率是PC或者NAS设备
    • 返回各厂商自定义IoT服务(比如米家、HomeKit相关服务)的对应智能硬件

multicast_dns基础调用示例

import 'package:multicast_dns/multicast_dns.dart';

// 存储mDNS查询结果的结构体
class LanDeviceInfo {
  final String ip;
  final String deviceName;
  final String serviceType;
  final int port;
  LanDeviceInfo({required this.ip, required this.deviceName, required this.serviceType, required this.port});
}

Future<List<LanDeviceInfo>> queryMDnsDevices() async {
  final client = MDnsClient();
  final List<LanDeviceInfo> res = [];
  // 启动mDNS客户端,绑定5353端口
  await client.start();
  try {
    // 遍历所有广播的服务
    await for (final ptrRecord in client.lookup<PtrResourceRecord>(
        ResourceRecordQuery.serverPointer('_services._dns-sd._udp.local'))) {
      // 查询对应服务下的具体设备
      await for (final srvRecord in client.lookup<SrvResourceRecord>(
          ResourceRecordQuery.service(ptrRecord.domainName))) {
        // 查询设备对应的IP地址
        await for (final ipRecord in client.lookup<IPAddressResourceRecord>(
            ResourceRecordQuery.addressIPv4(srvRecord.target))) {
          res.add(LanDeviceInfo(
            ip: ipRecord.address.address,
            deviceName: srvRecord.target,
            serviceType: ptrRecord.domainName,
            port: srvRecord.port,
          ));
        }
      }
    }
  } finally {
    client.stop();
  }
  return res;
}

注意事项

  • 没有方案能做到100%的设备类型识别率:部分用户会手动关闭设备的mDNS服务,这类设备只能通过OUI做粗粒度分类,可以在列表里提供手动修改设备类型的入口。
  • 权限适配:Android 10、iOS 14及以上版本必须在应用启动时申请本地网络权限,否则所有局域网扫描、ARP请求、mDNS查询都会被系统静默拦截,不会返回任何结果。
  • 扫描逻辑建议放在后台异步执行,不要阻塞主线程,扫描过程中可以实时把发现的设备追加到列表,不需要等全部扫描完成再展示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 16:12:17