ByteNoteByteNote
Windows 上的 mDNS 走 UDP 5353
字

字节笔记本

2026年10月7日 · 约 8 分钟读完

Windows 上的 mDNS 走 UDP 5353

API中转
¥120

同一台局域网里的打印机和电脑,经常靠名字而不是 IP 互相找到。这件事用的是 mDNS:查询发到多播地址,端口是 UDP 5353,没有单独一台 DNS 服务器。Windows 要参与,系统得听这个端口,防火墙也得放行。

mDNS 查询走 UDP 5353

系统服务先要在跑

对话里的第一条路是安装 Apple 的 Bonjour Print Services for Windows,里面带上 mDNS 需要的组件。装完之后,在 services.msc 里确认 Bonjour Service 处于运行。没有这个服务,只装了文件也不会回答多播查询。

第二条路是系统自带的实现。对话里写的是从 Windows 10 版本 1703 起,系统已经带 mDNS。版本太旧时,自带实现不存在,只能走 Bonjour 那条安装。升级到当时的系统更新之后,再查服务,而不是反复重装打印组件。

无论走哪条,DNS Client 服务都要在运行。mDNS 是 DNS 的一种问法,客户端服务停了,名字解析这条链是断的。打开服务管理器,看启动状态,不要只看防火墙。

防火墙放行 5353

mDNS 的对话在 UDP 5353。Windows 防火墙把这个端口丢掉时,服务在跑也收不到查询,自己发出的查询也没有回应。放行的是多播用的 UDP,不是随便开一个 TCP 入站。改完规则用两台在同一网段的机器试名字,不要用公网 IP 去试,mDNS 不出这一跳局域网。

名字通常长在 .local 下面。对方如果只登记了 IP,没有登记这个名字,端口通了也解析不到。先确认对方的设备确实在发 mDNS,再查自己这边的服务和防火墙。顺序反了会在防火墙规则里改很久。

公司网络如果隔离了多播,5353 在本机放行也到不了对方。那是交换机或无线的隔离,不是 Windows 服务没开。同一台 AP 下的两台电脑能互通、跨 AP 不能,就去看网络而不是再装一遍 Bonjour。

程序里用系统的头文件

要在自己的程序里登记或查询服务,对话里指向 Windows SDK 的 Dnssd.h。那是系统 API 的头,不是再去实现一套多播。应用层自己绑 UDP 5353 会和系统服务抢端口。系统已经有 Bonjour Service 或自带 mDNS 时,程序应该调用 API,而不是再开一个监听。

对话里也提到有人用 Avahi 或 mDNSResponder 这种第三方实现。那是在系统组件不够用、或要和别的平台共用同一套代码时的选择。Windows 上已经有服务在听 5353 时,再跑一个响应器,两个都会觉得自己该回答,结果不稳定。先停掉不用的那一个,再决定代码走 SDK 还是走第三方库。

打印服务只是 Bonjour 安装包的入口,装上之后 mDNS 并不只为打印机服务。别的设备用同一端口发布名字。不需要打印时,仍然要保证服务在跑、端口放行,名字才能被看见。

服务在跑,防火墙才放行端口

按顺序查,不要跳步

先看版本和组件。系统若早于对话里写的 Windows 10 1703,自带 mDNS 不在考虑范围内,去装 Bonjour Print Services for Windows。装完打开 services.msc,Bonjour Service 要是正在运行,而不是仅仅存在于列表里。启动类型保持会随系统起来,避免每次开机后名字又消失。

然后看 DNS Client,同样要正在运行。这个服务和 Bonjour Service 是两行。只启动其中一个,另一行停着,名字仍然会失败。服务管理器里看状态列,不要只看依赖关系的描述。

接着看防火墙。放行 UDP 5353。这是多播查询用的端口。改成 TCP、或者只允许远程 IP,都对不上 mDNS 的问法。规则加完,用同一局域网里的两台机器试 .local 名字。用公网地址试,失败不能说明端口没开,因为这种查询本来就不该离开这一跳。

最后才是自己的程序。Windows SDK 里的头文件是 Dnssd.h。登记和查询走这套 API。应用再 bind 到 UDP 5353,会和已经在听的服务冲突。第三方实现对话里点了 Avahi 和 mDNSResponder。选用它们的前提是系统服务不负责这件事。两个响应器同时听同一个端口,回答会不稳定。留下一个。

失败时先分清是哪一层

同一网段的两台电脑,一台看得到打印机、另一台看不到,先比服务状态和防火墙,而不是先改代码。两台都看不到,而手机在同一网络能看到,Windows 这边的服务或端口更可疑。跨无线网才失败,本机防火墙已经放行,就去看接入点是否隔离了多播。那一层不在 services.msc 里。

打印组件的名字容易让人以为只和打印机有关。装上之后,别的设备用同一套多播发布名字,端口仍是 5353。不打印也要服务在跑。反之,只想用 IP 访问、从不用名字,可以不装,没有 mDNS 并不影响已知 IP 的连接。

程序侧不要为了“更可控”再实现一个多播监听。系统已经有实现时,重复监听是故障来源。Dnssd.h 是对话里给出的入口。头文件里的调用需要链接 SDK,这是开发机上的事,和最终用户要不要安装 Bonjour 打印组件是两条线:用户机器靠服务,开发代码靠头文件。

先服务,再端口,再代码

Windows 上参与 mDNS,要么装 Bonjour 并让 Bonjour Service 运行,要么使用 Windows 10 1703 及之后自带的实现,同时保证 DNS Client 在跑。防火墙放行 UDP 5353。程序侧看 Dnssd.h,不要再私自占用这个端口。第三方响应器和系统服务只留一个。名字只在局域网的多播里有效。

验收时准备同一网段的两台机器。较新的系统先不装额外组件,确认版本不低于对话里写的 Windows 10 1703,DNS Client 正在运行,防火墙对 UDP 5353 放行,再用 .local 名字互访。失败再装 Bonjour Print Services,并在 services.msc 里把 Bonjour Service 启动。不要用公网 IP 判断多播是否工作。

自己的程序只包含 Dnssd.h 这一条系统入口。进程列表里若同时有系统服务和另一个 mDNS 响应器,停掉后来加的那个,再试一次名字解析。Avahi 或 mDNSResponder 只在确定不用系统实现时留下。端口被两个进程抢,现象是有时能解析、有时不能,看起来像防火墙间歇故障。

打印机只是安装包的名字。不需要打印的设备,只要在发 mDNS,同样走 5353。已知 IP、从不用名字的连接,不必为它打开这套服务。

服务、端口、代码三层不要并成一步安装。services.msc 里 DNS Client 和 Bonjour Service 都要处于运行。防火墙只放行 UDP 5353。程序只走 Dnssd.h,不再绑定这个端口。第三方库 Avahi 或 mDNSResponder 和系统服务互斥。名字留在局域网,解析失败时先换一台同网段的机器对照,再决定是不是要重装打印组件。组件的名字带 Print,并不表示只有打印机使用这条多播。端口号以对话里写的 UDP 5353 为准,不要改成邻近的端口再试。多播只在局域网里走。

相关文章

分享: