ESP-IDF网络编程之mDNS
重要说明
官网地址 mDNS 服务
注意:
之前使用esp8266完成了mDNS对主机域名解析,这次是想用这个办法使用在esp32中,本以为把之前文件直接复制就行了,谁知是不行的!查询发现是因为没有添加这个组件,官放已经迁出至独立的仓库!根据官方说明添加到组件库即可!
mDNS 是一种组播 UDP 服务,用来提供本地网络服务和主机发现。
自 v5.0 版本起,ESP-IDF 组件 mDNS
已从 ESP-IDF 中迁出至独立的仓库:
运行 idf.py add-dependency espressif/mdns
,在项目中添加 mDNS 组件。
托管的文档
请点击如下链接,查看 mDNS 的相关文档:
mDNS学习使用
mDNS的作用
mDNS 是一种组播 UDP 服务,用来提供本地网络服务和主机发现。
- 你要和设备通信,需要记住IP地址不好记。用了mDNS只要几个名字就行。
- 你需要快速知道局域网内是否有你想要的服务,用mDNS查一下就行。
- 这个协议只在局域网内有效。
- 先简单了解下什么是组播–一种被预先定义好的IP地址数字。用于实现一对多的通信。
1 | 组播是一对多。 |
mDNS涉及到的标准文件
组播地址
- 因为有IPV4和IPV6两类地址,因此组播也分两类。
- 多播地址在网络通信中用于发送数据到多个接收器,而不是单一接收器或广播到所有接收器。多播地址有其特定的规则和范围
IPv4 多播地址
IPv4 多播地址范围是 224.0.0.0 到 239.255.255.255。这些地址进一步细分为特定用途的子范围:
1 | 局部网络控制块: 224.0.0.0 到 224.0.0.255 |
IPv6 多播地址
IPv6 多播地址以 ff00::/8 前缀开头,并具有不同的范围标识符和子范围:
1 | 范围标识符(Scope Identifier): |
预先定义好的组播地址
不同的标准,如果用到组播地址,会定义出组播地址的值。下面列出常见的。
常见IPv4 预定义组播地址
这些地址用于局域网内的控制消息,通常不被路由器转发。
1 | 224.0.0.1: 所有主机 |
常见IPv4 预定义预留多播地址(224.0.1.0 - 238.255.255.255)
这些地址用于全球范围的多播应用,路由器会转发这些地址的数据包。
1 | 224.0.1.2: SGI-Dogfight(多用户虚拟现实游戏) |
常见IPv4 预定义本地管理地址(239.0.0.0 - 239.255.255.255)
这些地址用于组织内部的多播,不会被全球路由。
常见IPv6 预定义组播地址
范围标识符(Scope Identifier)
1 | ff01::: 节点本地(Node-Local) |
预定义多播地址
1 | ff02::1: 所有节点(All Nodes) |
备注:
“组播”和“多播”在网络通信中基本上是同一个概念。两者指的是同一种技术。
mDNS调试工具
在电脑端,有两款,
- 一款是Apple开发的Bonjour 的服务(有windows版本),这款我下载安装了,不会用尴尬,好像只能识别打印机服务。
- 一款是在linux平台下的avahi(默认已安装),也有图形界面。后面会有这款工具的截图。
例程
ESP的mDNS文档和例程都放在下面的git 库里面
- git下来后vscode打开例程。
- 设置wifi账号密码
编译和运行测试
运行命令avahi-discover,打开图形界面,如下所示。
点击任意一项,就可以看到解析出来的数据。如下所示。
直接ping域名也是可以ping通的
1 | ping esp32-mdns.local |
按下按钮0,打印如下信息。查询到局域网里有这些服务。
mDNS如何开发和使用
开发主要看需求,分两个需求:注册服务和查询服务。
根据自己的需求决定是否要做这两个动作。
下面只是把关键的代码片段拿出来,完整代码,请看例程。
初始化mdns
mdns_init() 这一步是通用的,不管是注册还是查询,都要先初始化。
注册服务
设置主机名
mdns_hostname_set(hostname)设置实例名
mdns_instance_name_set(EXAMPLE_MDNS_INSTANCE)注册服务
1
2mdns_service_add("ESP32-WebServer", "_http", "_tcp", 80, serviceTxtData, 3)
mdns_service_subtype_add_for_host("ESP32-WebServer", "_http", "_tcp", NULL, "_server")
查询服务
例程将查询服务做了一次封装,只需要输入服务名和使用协议,就可以查网络中是否存在有这个服务。
在例程里,只要按一下按钮0,就回调用这个函数,并将查询结果在串口打印。
1 | static void query_mdns_service(const char *service_name, const char *proto) |
上面的函数实际是调用库函数,实现查询
1 | mdns_query_ptr() |
相关链接(侵删)
欢迎到公众号来唠嗑: