在过去的二十年里,IP协议已经成为计算机等硬件设备之间通信的基本协议。大部分计算机和其它网络设备都是基于TCP/IP进行通信的。在这种网络中,每个设备都需要一个唯一的IP地址,不管是手动设定的还是由DHCP服务器动态分配的。动态指定的地址是可以改变的,但是像打印机等设备是必须手动设定一个静态地址的,这样网络中的计算机才能连接到它们。然后网络管理员需要配置一个DNS服务器,这样计算机用户就不需要通过IP地址来连接打印机了。这样,一个看起来很小的工作需要比较复杂的配置。但是如果我们需要在自己家中搭建一个局域网,而我们对此一无所知的话,这就是个大问题了。即使对于专业的网络管理员,也需要去手动配置打印机。但我们很多时候并不希望去做这些配置,就可以直接连入局域网内去获取打印机、或在文件服务器、甚至游戏服务器去获取我们想要的东西。
我们希望找到可用的设备并从一个列表中选择它们,而不是必须知道每个服务名或IP地址。这便是Bonjour所需要解决的问题。它是基于IP的一组零配置网络的协议。零配置网络有很大的潜力。
假设我们带着笔记本电脑去客户的公司,这时我们需要打印一些东西。如果这家公司有一台支持Bonjour协议的打印机,那么只要两台设备在同一个局域网内,就可以直接打印。此时,我们的每户本会搜索到任何可用的设备。我们只需要打开文档,选择设备列表中的打印机,点击打印就可完成打印操作。图1演示了这样一个过程:
这种零配置网络能够满足手机游戏、家庭网络、分布式计算和其它很多网络应用的需求。
那么Bonjour到底是什么呢?
Bonjour三要素
Bonjour是由苹果提出的基于IP的无配置网络建议。它产生于ZEROCONF工作组的工作,是IETF的一部分。ZEROCONF工作组对于基于IP的零配置网络的需要主要有三个要求
- 寻址(分配IP地址给主机)
- 命名(使用名字而非IP地址来表示主机)
- 服务搜索(自动搜索网络服务)
Bonjour即是这些需求的一个解决方案。它允许服务提供商、硬件制造商和程序开发者在使用新的技术时只使用单一的网络协议–IP。网络用户不再需要指定IP地址和主机名,甚至不需要指定网络中访问设备的类型。用户只需要简单的查看有哪些网络服务可用,然后从列表中选择。程序能自动检测到所需要的服务或它们需要进行交互的其它程序,允许自动连接、通信和进行数据传输,而不需要用户的介入。
下面我们来分别看看Bonjour如何解决零配置网络的三个要素
寻址
寻址问题通过自分配链路本地寻址方法来解决。链路本地寻址(Link-local addressing)使用为本地网络保留的地址范围,特别是一个小的LAN或单独的LAN片断。IPv6标准将自分配链路本地寻址作为协议的一部分。而IPv4本身不包含链路本地寻址,因此零配置网络寻址的主要挑战是如何在IPv4中改进此功能。
在IPv4中,自分配寻址通过在链路本地范围内挑选一个随机的IP地址并对其进行测试。如果地址没有使用,则作为本地地址。如果已经使用了,计算机或其它设备将选择另一个随机地址并测试。
目前大多数主流操作系统都支持IPv4和IPv6的链路本地寻址。
命名
在本地网络中进行name-to-address转换操作建议的方案是使用多播DNS,其中DNS格式查询使用IP多播传送到本地网络中。因为这些DNS查询被发送到多播地址中,因此没有一个全局的DNS服务器来回答这个查询。每个服务或设备都可以提供自己的DNS功能,当前发现一个针对自己名称的查询时,它使用自己的地址来响应这个DNS查询。
Bonjour更进了一步。它在主机或iOS设备上包含一个响应来处理任何网络服务的多播DNS查询。这降低了中断应用来响应多播消息的压力。通过注册服务,Bonjour的mDNSResponder守护进程自动广告我们的服务是否可用,以便把我们名字的查询自动被引导到正确的IP地址和端口号上。
为了让name-to-address转换能正确的工作,需要一个本地网络的唯一的名字。与转换DNS主机名不同的是,这个本地名称只在本地网络或LAN段上有效。我们可以像自分配一个本地地址一样自分配一个本地名称,选中其中一个;如果这个名称没有使用,则:
- 硬件制造商通过设备发送一个多播DNS查询并查看响应来确定其选中的名字是否已使用。如果有响应,则设备应该选择另外一个名字。没有用户界面的设备可以在默认名字后面添加一下大数直到这个名字是唯一的。例如,如果在网络中的默认名字是XYZ-LaserPrinter.local,则可以使用XYZ-LaserPrinter.local,XYZ-LaserPrinter-2.local,XYZ-LaserPrinter-3.local进行测试,直到名字唯一。
- 软件服务在注册Bonjour时提供一个名字,如果提供的名字已使用,则Bonjour会自动重命名我们的服务。
在OS X中,用户可以在系统偏好设置的共享面板中设置本地主机名来为计算机设置一个主机名,在iOS中,主机名是自动产生的且不能配置。这个主机名可用于任何DNS主机名常规使用的地方,如Web浏览器、命令行工具等等。为了向系统表明名字是一个本地主机名,可在主机名后添加.local.,如Setve.local.即为一个本地主机名。
如果用户在浏览器中输入steve.local.,这将告诉系统多播一个请求以在本地网络中查询steve,而不是将其发送到常规DNS服务器。如果在本地网络中有一台支持Bonjour的计算机名字为steve,则用户的浏览器将发送正确的IP地址给它。这允许用户访问本地主机和服务崦不需要常规DNS服务。
服务搜索
Bonjour最后一个要素是服务搜索。服务搜索允许程序查找所有可用的特定类型的服务并维护一个命名服务及端口的列表。应用可以将服务主机名解析为IPv4和IPv6地址列表。
命名服务的列表在服务与其当前DNS名和端口中提供了一个indirection层。indirection允许程序保存一个可用服务的持久化列表并在使用服务前解析一个实际的网络地址。该列表允许服务被动态迁移,而不会产生大量的网络流量来宣告这个改变。
在Bonjour中服务搜索是通过”browsing”来实现的。一个多播DNS查询发送一个指定的服务类型和域,任何匹配的服务都会回复他们的名字。其结果就是一个可用服务的列表。这与传统的网络服务以设备为中心的思考很不一样。对于处理服务、网络设备和网络编程的的个人来讲,很容易习惯性认为服务基于物理硬件(services in terms of physical hardware)。
从设备为中心的角度来看,网络由许多设备或主机组成,每个包含一组服务。例如,网络可能由服务器和客户机组成。在一个设备为中心的浏览架构中,一个客户端向服务器查询哪些服务正在运行,获取一个列表(FTP, HTTP等),并决定使用哪个服务。这个接口反映了物理系统组织的方式。但这不一定是用户在逻辑上希望的或想要的。
用户通常想要完成特定的任务,而不是查找设备列表来找出什么服务正在运行。让客户端只询问一次“什么打印服务可用?”比查询每个可用的设备来问“你正在运行什么服务”然后筛选结果查找打印服务来得更有意义。以设备为中心的方法不但耗时,而且需要大量的网络流量,且其中大部分是无用的。而以服务为中心的方法发送单个查询,只生成相关的回复。
此外,服务不与指定的IP或主机名绑定。例如,一个站点可能被多个有不同地址的服务器托管。在一个组织中,网络管理员可能需要将一个服务从一个服务器移到另一个服务器来做负载均衡。如果客户端存储了主机名,如果服务移到另一个不同的主机,则无法再连接。
Bonjour从面向服务的角度来看问题。它通过所需要的服务类型来查找,而不是主机名。应用存储的是服务实例名,而不是地址,所以如果IP地址、端口号,甚至主机名改变了,应用仍然可以连接。通过专注于服务而不是设备,用户的浏览体验将更有用且无故障。
降低消耗
服务器的寻址、命名和服务搜索可能会产生大量的网络流量,但Bonjour采取了一些措施来将流量降低到最少。这允许Bonjour达到AppleTalk的易用性,同时又避免了不必要的“繁琐”。Bonjour采用了多种机制来降低零配置的开销,包括缓存、禁止重复响应,指数回退和服务公告。下面我们将简单介绍下这几种机制。
缓存
Bonjour采用了多播DNS记录缓存来防止主机请求那些已请求过的信息。例如,当一个主机请求一个LPR打印后台的处理程序列表时,列表通过多播传回来,所有本地主机都将看到这个列表。下次本地网络中的一个主机需要一个打印后台处理程序的列表时,因为它已经缓存了这个列表,所以不需要再次发起请求。多播DNS响应者负责维护这个缓存;程序开发者不需要做任何事情来维护它
禁止重复响应
为了阻止重复响应相同的请求,Bonjour服务查询包含一个已知答案的列表。例如,如果主机正在浏览打印机,第一个查询不包含打印服务,但从可用打印服务器得到12个回复。下一次该主机查询打印服务时,查询包含已知服务器的列表。已经在列表中的打倒服务器将不做响应。
Bonjour以另一种方式来抑制重复响应。如果一个主机将要响应,但发现另一个主机已经响应了相同的信息,则主机会抑制它的响应。
程序开发者不需要采取任何措施来抑制重复发送,Bonjour会处理。
指数回退和服务公告
当主机浏览服务时,它不会不间断地发送查询来查看是否有新的服务。相反,主机会初始一个查询,后续会不断增加查询时间的间隔,如1s, 3s, 9s, 27s这样一个时长间隔,最后可能会长达1小时的间隔。
但这不意味着花费一个小时的时间间隔再来查看新的服务。当在网络中启动一个服务时,它会使用几次回退算法来通知它的存在。这样就将服务公告和搜索的网络流量保持在最小,而新的服务也会很快就知晓。
在一个Bonjour配置主机上运行的服务在注册到mDNSResponder守护程序时会自动发出公告。在其它硬件上的服务,如打印机,将使用指数回退算法来公告其存在,这样充分利用了Bonjour的优势。