Bonjour_mDNS_笔记

来源:互联网 发布:博客下载软件 编辑:程序博客网 时间:2024/06/05 07:24

参考文章:

http://www.2cto.com/kf/201701/551764.html

http://www.cnblogs.com/yuweifeng/p/6409182.html

https://github.com/GoogleChrome/chrome-app-samples/tree/master/samples/mdns-browser

https://github.com/jevinskie/mDNSResponder


Bonjour:零配置联网,基于mDNS协议和DNS-SD(DNS Service Discovery)协议,能自动发现IP网络上的电脑、设备和服务 

主要在缺少中心服务器的情况下解决IP获取、名称解析、服务发现三个问题 
基于组播的DNS服务(mDNS),只能在本地网络上工作LAN,不可通过WAN。 
Bonjour与微软的UPnP比较相似,都是在局域网上工作。 
1)IP获取_Addressing(在没有中心服务器提供DHCP服务情况下) 
IPV6:IPV6本身就提供设备自指定IP地址的能力,所以实现简单 
IPV4:Bonjour使用随机指定IP,并检查是否冲突

2)名称解析_Naming(在没有DNS服务解析情况下) 

使用mDNS,即组播DNS。使用.local作为本地域名的根域名,用于区分全球域名和本地域名 

当设备需要解析一个名称时,如”abc.local”,通过UDP向本地网络广播一个消息:谁是”abc.local”,对应设备给出回应,并给出自己IP地址

Bonjour的Naming有个限制,网络内部不能有重复的Hostname或Services

3)服务发现 _ Service Discovery
Bonjour按照”名称.服务类型.传输协议.local”,如“DamonWebServer._http._tcp.local.”

支持Bonjour的设备,需要实时监听mDNS的数据包并刷新DNS缓存。 
Bonjour的工作过程,包括:通告和查询 
通告:任何一个设备接入网络中,都需要通告全网自己设备的信息,如IP、端口、服务类型、是否有密码认证之类。 
查询:查询整个网络中是否有自己想要的服务或者是否有可供自己访问的一些服务,查询网络中是否存在冲突,查询目的主机的IP地址。

mDNS:Multicast DNS,在小范围本地网络中使用,与DNS相似的接口、数据包结构、操作语义的协议,但在本地网络中没有通常意义上的DNS Server。 
使用UDP,5353端口。 
广播地址:224.0.0.251(IPv4) or FF02::FB(IPv6) 

每个支持mDNS的主机进入局域网后,通过端口5353向局域网内所有的主机组播一个消息:主机类型和IP地址,然后其他支持mDNS服务的主机会响应。 
比如,A主机进入局域网,开启了mDNS服务,并向mDNS服务注册一下信息:我提供FTP服务,我的IP是192.168.1.101,端口是21。当B主机进入局域网,并向B主机的mDNS服务请求,我要找局域网内FTP服务器,B主机的mDNS就会去局域网内向其他的mDNS询问,并且最终告诉你,有一个IP地址为192.168.1.101,端口号是21的主机,也就是A主机提供FTP服务,所以B主机就知道了A主机的IP地址和端口号了。

Multicast DNS borrows heavily from the existing DNS protocol [RFC1034] [RFC1035] [RFC6195], using the existing DNS message structure, name syntax, and resource record types.


Apple通过开源工程mdnsresponder。Windows平台通过后台程序mdnsresponder。Android(或支持POSIX的linux平台)通过mdnsd。

Bonjour API 主要是服务注册、服务查询、服务解析,理解这三个函数的功能也是理解MDnsSdListener的基础

需要#include <dns_sd.h>头文件 ,连接到libmdnssd.so 

在Bonjour中,服务注册的API为 DNSServiceRegister,原型如下:


该函数的解释如下:

  • sdRef:代表一个未初始化的DNSService实体。其类型DNSServiceRef是指针。该参数最终由DNSServiceRegister函数分配内存并初始化。
  • flags:表示当网络内部有重名服务时的冲突处理。默认是按顺序修改服务名。例如要注册的服务名为“printer”,当检测到重名冲突时,就可改名为“printer(1)”。
  • interfaceIndex:表示该服务输出到主机的哪些网络接口上。值-1表示仅对本机支持,也就是该服务的用在loop接口上。
  • name:表示服务名,为空的话就取机器名。
  • regtype:服务类型,用字符串表达。Bonjour要求格式为"_服务名._传输协议",例如"_ftp._tcp"。目前传输协议仅支持TCP和UDP。
  • domian和host一般都为空。
  • port表示该服务的端口。如果为0的话,Bonjour会自动分配一个。
  • txtLen以及txtRecord字符串用来描述该服务。一般都设置为空。
  • callBack:设置回调函数。该服注册的请求结果都会通过它回调给客户端。
  • context:上下文指针,由应用程序设置。
当客户端需要搜索网络内部特定服务时,需要使用DNSServiceBrowser API,其原型如图2所示:


其中:

  • sdref、interfaceIndex、regtype、domain以及context含义与DNSServiceRegister一样。
  • flags:在本函数中没有作用。
  • callBack:为DNSServiceBrowser处理结果的回调通知接口。

当客户端想获得指定服务的IP和端口号时,需要使用DNSServiceResolve API,其原型如图3所示:


其中:

  • name、regtype和domain都从DNSServiceBrowse函数的处理结果中获得。
  • callBack用于通知DNSServiceResolve的处理结果。该回调函数将返回服务的IP地址和端口号。

如果需要了解Bonjour安卓中的使用方法及原理,请阅读该部分的原文: http://blog.csdn.net/innost/article/details/8629139


原创粉丝点击