链接

“多播” 协议是一个非常基础的协议, Apple 公司在此基础上提出了 “Zeroconf” 协议—- 网络零配置协议, Apple 上的 Bonjour 和 linux 上的 Avahi 都是对 “Zeroconf” 协议的实现.

为什么需要多路广播?

不使用多路广播, 通信的话需要对方的 ip 地址, 但是获取对方的 ip 地址有时比较麻烦.

在局域网内,你要通过一台主机和其他主机进行通信,你需要知道对方的 ip 地址,但是有些时候,你并不知道对方的 ip 地址,因为一般使用 DHCP 动态分配 ip 地址的局域网内,各个主机的 IP 地址是由 DHCP 服务器来帮你分配 IP 地址的。所以在很多情况下,你要知道对方的 IP 地址是比较麻烦的。

这段话不太正确: mDNS 是一种网络协议, 用于局域网内的服务发现. Apple 上 Bonjour 实现了此协议, Linux 上的 Zeroconf 实现了此协议. Zeroconf 依赖于 avahi 包.

zeroconf 协议

Zeroconf全称为Zero configuration networking,中文名则为零配置网络服务规范,是一种用于自动生成可用IP地址的网络技术,不需要额外的手动配置和专属的配置服务器。
“零配置网络服务”的目标,是让非专业用户也能便捷的连接各种网络设备,例如计算机,打印机等。整个搭建网络的过程都是通过程式自动化实现。如果没有zeroconf,用户必须手动配置一些服务,例如DHCP、DNS,计算机网络的其他设置等。这些对非技术用户和新用户们来说是很难的事情。
使用例子来形象地说明:
用户拥有一台apple tv和一台iPhone4s,那之只要都连入到同一个无线局域网内,iphone4s就会自动找出apple tv,那么在播放音乐或者视频时候,用户只要点击推送,就可以讲音乐和视频推送到apple tv上播放。

zeroconf协议的实现

zeroconf是协议,因此对应的是各种产品的实现,现在最主要的实现是apple的Bonjour和开源的Avahi。
这两套实现在程序接口上是可以兼容的,因此可以对zeroconf技术依赖的产品,可以使用兼容的开发接口,而不需要考虑到底是使用了Bonjour还是avahi。

Apple的zeroconf协议技术实现 – Bonjour

Bonjour是由apple实现的zeroconf协议的技术产品,Bonjour来源于法语,意思为你好。
使用了zeroconf技术的产品和服务,在网络中自动传播它们自己的服务信息并聆听其它设备的服务信息,设备之间就象在打招呼,这也是命名为Bonjour(法语:你好)的原因。
Bonjour是一套跨平台的产品,可以使用在Mac,Linux和Winows,以及是兼容POSIX的操作系统上,并且apple已经將其开源,所以也可以方便应用于各个产品。
Bonjour是由纯C编写的,同时也提供了Java的接口,目前如python或者ruby语言也可以很方便地调用使用它。

开源的zeroconf协议技术实现 – Avahi

Avahi 是Zeroconf规范的开源实现,基本是使用在Linux和FreeBSD上。包含了一整套多播DNS(multicastDNS)/DNS-SD网络服务的实现,使用的发布授权是LGPL。
在程序接口上,它使用DNSD与apple的Bonjour进行兼容,方便原来使用Bonjour的产品进行迁移。
目前在绝大多数的Linux发行版本中,都讲avahi作为系统启动进程,并且大量的服务也依赖于avahi。
Avahi也是用纯C编写的,同样也可以使用诸如Java的语言去调用使用开发产品或者服务。

mDNS 的工作原理

mDNS 的默认地址

首先,在 IP 协议里规定了一些保留地址,其中有一个是 224.0.0.251,对应的 IPv6 地址是 [FF02::FB]。

mDNS 的端口时 5353

mDNS 协议规定了端口为 5353,而 DNS 的端口是 53

mDNS 基于 UDP 协议

mDNS 基于 UDP 协议。DNS 一般也是基于 UDP 协议的,但是也可以使用 TCP 协议。

mDNS 与 DNS 协议的区别

如果理解了 DNS 协议,再去理解 mDNS 协议就很简单了,区别只是:

  • 作用范围: mDNS 一般作用在一个局域网内的;
  • 特定的 IP 地址,也就是 224.0.0.251,
  • 特定的端口 5353,
  • mDNS 的作用是实现局域网内的服务发现,查询,注册,DNS 作用是实现域名的解析,作用大概是一样的。

    局域网主机需要广播

    每个进入局域网的主机,如果开启了 mDNS 服务的话,都会向局域网内的所有主机组播一个消息,我是谁,和我的IP地址是多少。然后其他也有该服务的主机就会响应,也会告诉你,它是谁,它的 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 地址和端口号了。

大概的原理就是这样子,mDNS 提供的服务要远远多于这个,当然服务多但并不复杂。

各种平台对 mDNS 的支持现状

  • 在 Apple 的设备上(电脑,笔记本,iphone,ipad等设备)都提供了这个服务。(因为好像就是 Apple 发明出来的)
  • 很多 Linux 设备也提供这个服务。
  • Windows 的设备可能没有提供,但是如果安装了 iTunes 之类的软件的话,也提供了这个服务。
  • 安卓系统. jmDNS 是一个 JAVA 平台的,提供 mDNS 服务的第三方库。在这个 jar 包引入到 Android 项目里,就可以获得 mDNS 服务了。Android 在 3.x 还是 4.x 之后已经提供局域网内自动发现的 API 了,所以不需要使用 jmDNS 第三方库就能实现了。

    应用场景

    聊天室

    分布式通信

    物联网

    移动设备

  • macos 上的设备发现

    linux/macos

  • [Cocoa]深入浅出Cocoa之Bonjour网络编程

    小程序

    https://www.jianshu.com/p/e66b0d400807