1. 引言
多播(或叫组播,Multicast)的出现,正是为了解决广播的不足。我们已经学会用 udp 发广播数据包,然而,对于不想接收广播数据包的主机来说,这就是一种骚扰。比如某主机接收到以太网帧(目的 MAC 地址为 ff:ff:ff:ff:ff:ff),一路沿着协议栈往上解包,到达 UDP 层,根据端口进行分发,但是并没有任何进程在这个端口监听,从而不得不丢弃这个数据包,这无疑是一种对资源的浪费。
而多播,正是解决此问题,只有想接收多播数据包的主机,才会接收数据,不想接收的,就直接忽视。
2. 实验
实验环境:http://git.oschina.net/ivan_allen/unp
gns3 工程:unp/protocol/gns3/demo02
我们以图 1 中的例子来说明。这个网络拓扑是我们之前学习广播时搭建的,只是在其基础上做了以下修改:
- 开启路由器 R1 和 R2 的多播功能
- 将 PC1、PC4 和 PC5 加入了组 230.4.4.4
- 将 PC2、PC3 和 PC6 加入了组 230.2.2.2
图1 网络拓扑
现在,你必须把 230.4.4.4 和 230.2.2.2 理解成组编号,就像 QQ 群号一样,它并不是普通意义上 A、B、C 类的 IP 地址,而是 D 类 IP 地址,它表示的是组编号。后面我们还会继续学习。
然后,通过一些设置方法,将不同的主机加入不同的组(类似加入不同的 QQ 群)先不要管我是如何将不同的主机加入不同组的,你只要知道结果就行,后面你会学会的。
注意:下面的实验可能一开始并不能成功,因为路由器之间以及主机和路由器之间交换多播信息需要很长时间才能完成,打开 GNS3 后,如果得不到结果,你可以耐心等待几分钟(超过 10 分钟也是可能的),再进行实验。
- 实验一
在 PC1 上 ping 230.4.4.4 和 230.2.2.2
图2 主机 PC1 上 ping 两个组
可以看到,只有加入相应组的主机,才会回复 PC1. 另一方面我们发现,尽管主机 192.168.3.100 (PC4)和 PC1 不在一个网段,也能收到 PC1 发来的数据,这是广播所做不到的。
- 实验二
这次,我们在 PC4 上 ping 两个组。
图3 在 PC4 上 ping 两个组
从图 3 的结果中可以看到,相应的组员都能正确的对 PC4 的 ping 请求做回应。
3. 多播
多播的魅力正如上一小节实验中看到的那样,它比广播好用,而且高效。但是它实现起来,自然也会比广播复杂的多。
正如实验中的那样,首先要把你的主机(网卡接口)加入某个多播组。当你向某个多播组发数据时,只有加入该组的成员才能收到数据。这就好比你像某个 QQ 群发消息,只要加入该群的所有人,都能收到消息一样。
在 Linux/Unix 中,可以使用套接字选项(后面会详细说),来控制某个网卡接口加入和离开某个多播组。
而发数据的时候,仍然可以像普通的客户端一样,把多播 ip 地址当成普通 ip 地址来使用。发送者是不是多播组的成员并不重要,这无所谓。
默认情况下,路由器是不开启多播功能的,这也意味着平常使用的路由器根本不会转发多播数据包。
对于开启了多播功能的路由器,它们之间使用多播路由选择协议进行交流(思科路由器使用 PIM 协议,Protocol Independent Multicast)。如果某个主机加入了多播组,该主机就首先会主动发送 IGMP 协议数据包(目标IP地址就是多播地址),路由器收到 IGMP 数据包后,会与其它路由器使用多播路由选择协议进行交流。随后,路由器会定期的发送 IGMP 查询数据包。
图4 路由器定期发送 IGMP 查询报文
如果某个路由器掌管的网络(同时与其连接的其它网络)没有相应的组成员,它是不会收到该组的数据包的。
比如图 1 中,在 PC1 上 ping 230.2.2.2 这个组,路由器 R1 根本不会将数据包从出口 192.168.1.1 出口转发给路由器 R2. 因为此出口上没有任何主机在 230.2.2.2 这个组。路由器就是根据 IGMP 协议和多播路由选择协议来掌握这些信息的。
4. 总结
- 初步掌握多播的概念
- 多播组就像 QQ 群,有自己的组号,这个组号是 D 类 ip 地址
- 了解 D 类 ip 地址
- 初步了解 IGMP 协议的作用