Flutter for OpenHarmony:multicast_dns 发现局域网设备,实现零配置网络 (mDNS/Bonjour/Zeroconf)(本地服务发现) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:multicast_dns 发现局域网设备,实现零配置网络 (mDNS/Bonjour/Zeroconf)(本地服务发现) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net

在这里插入图片描述

前言

在智能家居、打印机共享、P2P 文件传输等场景中,设备往往通过局域网互联。但 IP 地址是动态分配的,用户不可能去记 192.168.1.105。mDNS(Multicast DNS)允许设备在没有 DNS 服务器的情况下,通过 .local 域名互相发现。

multicast_dns 是 Dart 官方提供的库,用于发送和接收 mDNS 报文。你可以用它来查找局域网内的 HTTP 服务、Google Cast 设备,或者广播自己的服务供他人发现。

一、概念介绍/原理解析

1.1 基础概念

  • Multicast (组播): 向特定组播地址(224.0.0.251)发送数据包,局域网所有设备都能收到。
  • Service Type (服务类型): 如 _http._tcp (Web 服务), _googlecast._tcp (Chromecast)。
  • Record (记录): SRV (端口), TXT (元数据), A (IP)。

查询: _http._tcp.local

响应: 佳能打印机 @ 192.168.1.5

响应: 客厅电视 @ 192.168.1.8

手机终端

局域网组播

打印机

电视机

1.2 进阶概念

虽然 iOS/Android/macOS 系统层面都有 mDNS 服务(Bonjour/NsdManager),但 multicast_dns 是在 Dart 层直接操作 UDP Socket 实现的,因此跨平台一致性较好,但也受制于 Socket 权限。

二、核心 API/组件详解

2.1 基础用法

搜索局域网内的 Google Cast 设备。

import'package:multicast_dns/multicast_dns.dart';voidmain()async{final client =MDnsClient();await client.start();// 查询指针记录 (PTR)awaitfor(final ptr in client.lookup<PtrResourceRecord>(ResourceRecordQuery.serverPointer('_googlecast._tcp.local'),)){print('发现设备: ${ptr.domainName}');// 进一步查询详情 (SRV, IP)awaitfor(final srv in client.lookup<SrvResourceRecord>(ResourceRecordQuery.service(ptr.domainName),)){print('端口: ${srv.port}, 主机: ${srv.target}');}} client.stop();}
在这里插入图片描述

2.2 广播服务

目前库主要侧重于 客户端查询。要想作为服务端广播,通常需要更底层的 API 或者依赖平台插件(如 nsd)。但若是纯 Dart 环境,可以手动构造响应包(较复杂)。

三、常见应用场景

3.1 场景 1:查找打印机

搜索 _ipp._tcp_printer._tcp 服务。

awaitfor(final ptr in client.lookup<PtrResourceRecord>(ResourceRecordQuery.serverPointer('_ipp._tcp.local'),)){print('Found Printer: ${ptr.domainName}');}
在这里插入图片描述

3.2 场景 2:局域网对战游戏

两台手机进入同一 WiFi,互相发现对方建立连接。

// 搜索自定义的游戏服务类型final query =ResourceRecordQuery.serverPointer('_mygame._udp.local');awaitfor(final ptr in client.lookup<PtrResourceRecord>(query)){// 连接到发现的对战房间_connectToRoom(ptr.domainName);}
在这里插入图片描述

3.3 场景 3:开发调试

在 PC 开启服务,手机自动寻找调试端口,免去手动输入 IP。

// PC端可能通过 avahi 广播了 _debug._tcpfinal srv =await client.lookup<SrvResourceRecord>(ResourceRecordQuery.service('pc-debug._debug._tcp.local'),).first;print('Connect to Debugger: ${srv.target}:${srv.port}');
在这里插入图片描述

四、OpenHarmony 平台适配

4.1 组播权限与锁

在移动设备上监听组播需要特殊权限,并且在某些省电模式下,系统会过滤组播包。在 OpenHarmony 上,记得申请 INTERNET 权限。

4.2 网络绑定

多网卡设备(如同时开启 WiFi 和热点)可能导致 mDNS 发到了错误的网卡。MDnsClient 允许指定 RawDatagramSocket.bind 的参数。如果您发现搜不到设备,尝试检查网络接口。

五、完整示例代码

本示例构建一个局域网设备扫描器,列出所有 HTTP 服务 (_http._tcp)。

import'package:flutter/material.dart';import'package:multicast_dns/multicast_dns.dart';voidmain(){runApp(constMaterialApp(home:MDnsPage()));}classMDnsPageextendsStatefulWidget{constMDnsPage({super.key});@overrideState<MDnsPage>createState()=>_MDnsPageState();}classServiceInfo{finalString name;finalString host;final int port;finalString ip;ServiceInfo(this.name,this.host,this.port,this.ip);}class _MDnsPageState extendsState<MDnsPage>{finalList<ServiceInfo> _services =[]; bool _scanning =false;MDnsClient? _client;Future<void>_startScan()async{setState((){ _services.clear(); _scanning =true;}); _client =MDnsClient();await _client!.start();try{// 1. 查找服务实例 (PTR)awaitfor(final ptr in _client!.lookup<PtrResourceRecord>(ResourceRecordQuery.serverPointer('_http._tcp.local'),)){// 2. 查找服务详情 (SRV)awaitfor(final srv in _client!.lookup<SrvResourceRecord>(ResourceRecordQuery.service(ptr.domainName),)){// 3. 查找 IP (A)awaitfor(final ip in _client!.lookup<IPAddressResourceRecord>(ResourceRecordQuery.addressIPv4(srv.target),)){final info =ServiceInfo( ptr.domainName, srv.target, srv.port, ip.address.address,);if(mounted){setState((){if(!_services.any((s)=> s.ip == info.ip && s.port == info.port)){ _services.add(info);}});}}}}}finally{ _client?.stop();if(mounted)setState(()=> _scanning =false);}}@overridevoiddispose(){ _client?.stop();super.dispose();}@overrideWidgetbuild(BuildContext context){returnScaffold( appBar:AppBar(title:constText('局域网 HTTP 服务发现')), body:Column( children:[if(_scanning)constLinearProgressIndicator(),Expanded( child: _services.isEmpty ?constCenter(child:Text('没有发现 HTTP 服务,请确保 WiFi 连接')):ListView.builder( itemCount: _services.length, itemBuilder:(context, index){final s = _services[index];returnListTile( leading:constIcon(Icons.computer), title:Text(s.name.replaceAll('._http._tcp.local','')), subtitle:Text('${s.host}:${s.port} (${s.ip})'),);},),),],), floatingActionButton:FloatingActionButton( onPressed: _scanning ?null: _startScan, child:constIcon(Icons.refresh),),);}}
在这里插入图片描述

六、总结

multicast_dns 是 Dart 原生的 mDNS 解决方案。虽然不如原生 API 稳定(受限于 UDP 组播环境),但其跨平台一致性和灵活性是巨大的优势。

最佳实践

  1. 超时:mDNS 查询可能永远挂起(如果没有响应),务必结合 timeout 或手动 stop
  2. 缓存:设备名称与 IP 的映射关系应有短时缓存,减少网络风暴。
  3. 兼容性:Android/OpenHarmony 某些版本默认禁止后台组播,确保 App 前台运行且权限正确。

Read more

假网站排全网第二,真官网翻五页都找不到!NanoClaw创始人破防:SEO之战,我快要输了

假网站排全网第二,真官网翻五页都找不到!NanoClaw创始人破防:SEO之战,我快要输了

整理 | 苏宓 出品 | ZEEKLOG(ID:ZEEKLOGnews) 自从 OpenClaw 爆火之后,各种“Claw”项目接连出现,其中以安全优化版 NanoClaw 最为知名。它的核心代码仅有 4000 行,却获得了 AI 大牛 Andrej Karpathy 的点赞。 可谁也没想到,这款口碑极佳的开源项目,近来竟被一个仿冒网站抢了风头。 投诉无门之下,NanoClaw 创始人 Gavriel Cohen 在 X 社交平台上无奈发文怒斥:谷歌搜索错误地将假网站排在真官网前面,不仅破坏了项目声誉,还埋下了严重的安全隐患,而他费尽心力,却只能哀叹一句——“我正在为自己的开源项目打 SEO 战,但我快要输了。” 那么,NanoClaw 究竟发生了什么?又是怎么走红的?事情还要从 OpenClaw

By Ne0inhk
曝Windows 12将于今年发布?以AI为核心、NPU成「硬件门槛」,网友吐槽:“不想要的全塞进来了”

曝Windows 12将于今年发布?以AI为核心、NPU成「硬件门槛」,网友吐槽:“不想要的全塞进来了”

整理 | 郑丽媛 出品 | ZEEKLOG(ID:ZEEKLOGnews) 当年,微软一句“Windows 10 将是最后一个版本”的表态,让不少用户以为 Windows 进入了“只更新、不换代”的时代。但几年过去,现实却完全不同。 在 Windows 11 发布之后,如今关于 Windows 12 的传闻再次密集出现。从内部代号、代码片段,到硬件厂商的暗示与 OEM 预热标签,种种线索拼在一起,勾勒出一个明显的趋势——这不会只是一次常规升级,而更像是一次围绕 AI 的平台级重构。 更关键的是,这次争议,可能远比当年 TPM 2.0 更大。 精准卡位 Windows 10 退场的时间?

By Ne0inhk
“裸奔龙虾”数量已达27万只,业内人士警告;AI浪潮下,中传“砍掉”翻译等16个专业;薪资谈判破裂,三星电子8.9万人要罢工 | 极客头条

“裸奔龙虾”数量已达27万只,业内人士警告;AI浪潮下,中传“砍掉”翻译等16个专业;薪资谈判破裂,三星电子8.9万人要罢工 | 极客头条

「极客头条」—— 技术人员的新闻圈! ZEEKLOG 的读者朋友们好,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧。(投稿或寻求报道:[email protected]) 整理 | 郑丽媛 出品 | ZEEKLOG(ID:ZEEKLOGnews) 一分钟速览新闻点! * “裸奔龙虾”已高达27万只!业内人士警告:一旦黑客入侵,敏感信息一秒搬空 * 阿里云 CTO 周靖人代管千问模型一号位,刘大一恒管理更多团队 * 中国传媒大学砍掉翻译、摄影等 16 个本科专业,直言教育要面向人机分工时代 * 雷军放话:小米将很快推出 L3、L4 的驾驶 * 消息称原理想汽车智驾一号位郎咸朋具身智能赛道创业 * vivo 前产品经理宋紫薇创业,瞄准 AI 时尚Agent,获亿元融资 * MiniMax 发布龙虾新技能,股价暴涨超 23% * 薪资谈判破裂,三星电子

By Ne0inhk
Python热度下滑、AI能取代搜索引擎?TIOBE最新榜单揭晓!

Python热度下滑、AI能取代搜索引擎?TIOBE最新榜单揭晓!

整理 | 屠敏 出品 | ZEEKLOG(ID:ZEEKLOGnews) 日前,TIOBE 发布了最新的 3 月编程语言榜单。整体来看,本月排名变化不算大,但榜单中仍然出现了一些值得关注的小波动。  AI 工具能帮大家秒懂最新编程语言趋势? 由于 2 月天数较少,3 月的榜单整体变化有限。借着这次发布,TIOBE CEO Paul Jansen 也回应了一个最近被频繁讨论的问题:为什么 TIOBE 指数仍然依赖搜索引擎统计结果?在大语言模型流行的今天,直接询问 AI 哪些编程语言最流行,是不是更简单? 对此,Jansen 的回答是否定的。 他解释称,TIOBE 指数本质上统计的是互联网上关于某种编程语言的网页数量。而大语言模型的训练数据同样来自这些网页内容,因此从信息来源来看,两者并没有本质区别。换句话说,LLM 的判断,本质上也是建立在这些网页数据之上的。 Python 活跃度仍在下降

By Ne0inhk