本文由嵌入式企鹅圈原创团队成员-华南师范大学物联网创新中心Hende_Zhu先生执笔。
WIFI物联网解决方案中,通常我们需要对设备进行绑定,需要通过某种方法先对设备进行发现,比如微信硬件采用广播的方式,定时向外发送上线消息或者采用一问一答的方式进行发现,Bonjour是由苹果公司实现的一种零配置网络(Zeroconf)协议,它是一种基于服务的设备发现协议,不仅能够自动获取有效IP地址,还可以通过查询服务的方式来找到设备地址,只要双方约定好服务(service)的名称,设备的IP地址和端口都是可以变化的!
一、mDNS协议和DNS-SD协议
Bonjour协议是基于mDNS(Multicast DNS)协议和DNS-SD(DNS Service Discovery)协议开发实现,因此有必要先在这里给大家介绍一下这两个协议。
1.1 mDNS协议介绍
mDNS协议适用于局域网内没有DNS服务器时的域名解析,设备通过组播的方式交互DNS记录来完成域名解析,约定的组播地址是:224.0.0.251,端口号是5353,mdns协议使用DNS协议一样的数据包,由头部和数据段两部分(大家可以自行去了解DNS数据包的格式啦,在这里不展开介绍了):
mDNS的一个使用情景是这样的:
1.2 DNS-SD协议介绍
接下来再介绍一下DNS-SD协议,即DNS based Service Discovery,基于DNS的服务发现主要用到DNS现有的三种类型记录(Record Type):PTR记录、SRV记录、TXT记录,其中:
1)服务发现:设备会先发送一个查询PTR记录的数据包到组播组,所查询服务格式为:
可以看出,DNS-SD的PTR记录所代表的意思是区别于传统DNS的PTR记录的含义的,并且DNS-SD下的PTR记录用于记录服务到服务实例的映射。
2)获取服务实例的主机名和端口号:上述多个服务实例instance显示供用户选择确定一个后,就需要查询记录服务实例的主机名和端口号,即查询SRV记录。
设备会发送一个mDNS请求,然后具有所请求中服务实例的设备会响应SRV记录,SRV记录记录了这个服务实例对应的主机名和端口号以及TTL信息,一条SRV记录的例子是:
因此SRV记录用于记录服务实例到端口号和主机名的映射,即便端口号可变也没有关系。
3)服务实例更详细的信息:有时候,一个服务实例除了所在设备的端口号和主机名这些信息以外,还可以提供更多的附加参数信息,服务实例的附加信息记录在TXT记录中,以”key = value”的格式记录,如提供设备的MAC地址:
二、Bonjour协议原理
前面介绍了mDNS协议以及DNS-SD协议,其实基本上就已经展开介绍了Bonjour协议的细节,接下来再来理解Bonjour就相当轻松了。Bonjour协议可以理解为mDNS协议和DNS-SD协议的结合,其实大家在继续往下看之前可以自己想一下如何将两个协议结合起来呢?DNS-SD已经找到了提供服务的端口号和主机好了,最后再做进一步的主机名到IP地址的解析就完成了Bonjour协议的整个过程,当然结合的时候DNS-SD所发送的三种记录都是通过mDNS规定的组播组和端口号(224.0.0.254:5353)发送出去的,但是DNS-SD是不依赖mDNS协议而存在的。
Bonjour协议提供三部分功能:通告服务、发现服务、解析服务,这是三个动宾词组哈。在物联网中,设备在本地记录一个服务往往需要提供服务相关的SRV记录、PTR记录以及TXT记录相关的信息,用于最后组装mDNS数据包发送出去。
在没有DHCP分配IP地址和没有设置静态IP地址情况下,通过Bonjour协议还可以自己在局域网内获取有效的IP地址以及主机名,但是需要我们配置好路由的信息如子网掩码等,它会生成一个IP,然后询问局域网内是否有冲突,如果没有冲突就将这个IP占为己有,如果有冲突,就会更换一个IP,继续查询,主机名也是利用同样的方法获得。
通告服务用于设备告之局域网内其他人本设备的服务信息,一般包括发送SRV记录和PTR记录,这些记录被其它mDNS设备记录在本地的存储区中。
庆科物联的设备端已经实现了Bonjour协议的主要功能,以下是基于其设备端发现过程用Wireshark抓的包,其中IP地址为192.168.191.2表示的是手机端,192.168.191.3表示的是完成配网后的设备端,它们在同一个局域网内。
服务发现:由手机APP发送查询_easylink._tcp.local服务
嵌入式企鹅圈原创团队由阿里、魅族、nvidia、龙芯、炬力、拓尔思等资深工程师组成。百分百原创,每周两篇,分享嵌入式、Linux、物联网、GPU、Android、自动驾驶等技术。欢迎扫码关注微信公众号:嵌入式企鹅圈,实时推送原创文章!