目录
- mDNS的作用
- mDNS涉及到的标准文件
- 组播地址
- IPv4 多播地址
- IPv6 多播地址
- 预先定义好的组播地址
- mDNS调试工具
- 例程
- mDNS如何开发和使用
- 注册服务
- 查询服务
mDNS的作用
mDNS 是一种组播 UDP 服务,用来提供本地网络服务和主机发现。
- 你要和设备通信,需要记住IP地址不好记。用了mDNS只要几个名字就行。
- 你需要快速知道局域网内是否有你想要的服务,用mDNS查一下就行。
- 这个协议只在局域网内有效。
- 先简单了解下什么是组播–一种被预先定义好的IP地址数字。用于实现一对多的通信。
组播是一对多。
广播是一对所有。
mDNS涉及到的标准文件
- rfc6762
- rfc6763
组播地址
- 因为有IPV4和IPV6两类地址,因此组播也分两类。
- 多播地址在网络通信中用于发送数据到多个接收器,而不是单一接收器或广播到所有接收器。多播地址有其特定的规则和范围
IPv4 多播地址
IPv4 多播地址范围是 224.0.0.0 到 239.255.255.255。这些地址进一步细分为特定用途的子范围:
局部网络控制块: 224.0.0.0 到 224.0.0.255这些地址保留用于本地网络内的协议控制消息,不会被路由器转发到其他网络。例如,224.0.0.1 是所有主机的多播地址,224.0.0.2 是所有路由器的多播地址。预留多播地址: 224.0.1.0 到 238.255.255.255这些地址用于全球范围的多播应用,且路由器会转发这些地址的数据包。本地管理地址: 239.0.0.0 到 239.255.255.255这些地址保留用于组织内部的多播,不会被全球路由。
IPv6 多播地址
IPv6 多播地址以 ff00::/8 前缀开头,并具有不同的范围标识符和子范围:
范围标识符(Scope Identifier):ff01:: 链路本地(Link-Local)ff02:: 本地网络(Local Network)ff05:: 站点本地(Site-Local)ff08:: 组织本地(Organization-Local)ff0e:: 全球范围(Global)预定义多播地址:ff02::1 所有节点地址(所有主机)ff02::2 所有路由器地址
预先定义好的组播地址
不同的标准,如果用到组播地址,会定义出组播地址的值。下面列出常见的。
常见IPv4 预定义组播地址
这些地址用于局域网内的控制消息,通常不被路由器转发。
224.0.0.1: 所有主机
224.0.0.2: 所有路由器
224.0.0.4: DVMRP 路由器
224.0.0.5: OSPF 路由器
224.0.0.6: OSPF 指定路由器
224.0.0.9: RIPv2 路由器
224.0.0.10: EIGRP 路由器
224.0.0.13: PIM 路由器
224.0.0.18: VRRP 路由器
224.0.0.22: IGMPv3
224.0.0.251: mDNS (Multicast DNS)
224.0.0.252: Link-Local Multicast Name Resolution (LLMNR)
224.0.1.1: NTP (Network Time Protocol)
224.0.1.22: H.323 网关发现
常见IPv4 预定义预留多播地址(224.0.1.0 - 238.255.255.255)
这些地址用于全球范围的多播应用,路由器会转发这些地址的数据包。
224.0.1.2: SGI-Dogfight(多用户虚拟现实游戏)
224.0.1.35: SVRLOC (Service Location Protocol)
224.0.1.60: AAP (AOL Access Protocol)
239.255.255.250: SSDP (Simple Service Discovery Protocol)
常见IPv4 预定义本地管理地址(239.0.0.0 - 239.255.255.255)
这些地址用于组织内部的多播,不会被全球路由。
常见IPv6 预定义组播地址
范围标识符(Scope Identifier)
ff01::: 节点本地(Node-Local)
ff02::: 链路本地(Link-Local)
ff05::: 站点本地(Site-Local)
ff08::: 组织本地(Organization-Local)
ff0e::: 全球范围(Global)
预定义多播地址
ff02::1: 所有节点(All Nodes)
ff02::2: 所有路由器(All Routers)
ff02::5: OSPF 路由器
ff02::6: OSPF 指定路由器
ff02::9: RIPv2 路由器
ff02::a: EIGRP 路由器
ff02::d: PIM 路由器
ff02::16: MLDv2(Multicast Listener Discovery version 2)
ff02::fb: mDNS (Multicast DNS)
ff02::1:3: Link-Local Multicast Name Resolution (LLMNR)
ff05::1:3: DHCPv6 服务器/中继代理
备注:
“组播”和“多播”在网络通信中基本上是同一个概念。两者指的是同一种技术。
mDNS调试工具
在电脑端,有两款,
- 一款是Apple开发的Bonjour 的服务(有windows版本),这款我下载安装了,不会用尴尬,好像只能识别打印机服务。
- 一款是在linux平台下的avahi(默认已安装),也有图形界面。后面会有这款工具的截图。
例程
ESP的mDNS文档和例程都放在下面的git 库里面
例程
- git下来后vscode打开例程。
- 设置wifi账号密码
编译和运行测试
运行命令avahi-discover,打开图形界面,如下所示。
点击任意一项,就可以看到解析出来的数据。如下所示。
直接ping域名也是可以ping通的
ping esp32-mdns.local
按下按钮0,打印如下信息。查询到局域网里有这些服务。
mDNS如何开发和使用
开发主要看需求,分两个需求:注册服务和查询服务。
根据自己的需求决定是否要做这两个动作。
下面只是把关键的代码片段拿出来,完整代码,请看例程。
初始化mdns
mdns_init() 这一步是通用的,不过是注册还是查询,都要先初始化。
注册服务
1.设置主机名
mdns_hostname_set(hostname)
2.设置实例名
mdns_instance_name_set(EXAMPLE_MDNS_INSTANCE)
3.注册服务
mdns_service_add("ESP32-WebServer", "_http", "_tcp", 80, serviceTxtData, 3)
mdns_service_subtype_add_for_host("ESP32-WebServer", "_http", "_tcp", NULL, "_server")
查询服务
例程将查询服务做了一次封装,只需要输入服务名和使用协议,就可以查网络中是否存在有这个服务。
在例程里,只要按一下按钮0,就回调用这个函数,并将查询结果在串口打印。
static void query_mdns_service(const char *service_name, const char *proto)
上面的函数实际是调用库函数,实现查询
mdns_query_ptr()