欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

多播

程序员文章站 2022-07-06 22:57:25
...

概述

多播地址标识一组IP接口
多播既可用于局域网,也可用于广域网

多播地址

IPv4的D类地址

IPv4的D类地址[从224.0.0.0到239.255.255.255]是IPv4多播地址
D类地址的低序28位构成多播组
整个32位地址称为组地址

IPv4多播地址到以太网地址的映射方法

多播

以太网地址的高序24位总是01:00:5e
下一位总是0
低23位复制自多播组ID的低序23位
多播组ID的高序5位在映射过程中被忽略
32个多播地址映射成单个以太网地址
以太网地址首字节的低序2位标明该地址是一个统一管理的组地址
统一管理属性位意味着以太网地址的高序24位由IEEE分配
组地址属性位由接收接口识别并特殊处理

若干特殊的IPv4多播地址:
- 224.0.0.1
所有主机组
子网上所有有多播能力的节点[主机/路由器/打印机等]
必须在所有具有多播能力的接口上加入该组
- 224.0.0.2
所有路由器组
子网上所有多播路由器必须在所有具有多播能力的接口上加入该组
- 介于224.0.0.0到224.0.0.225之间的地址称为链路局部的多播地址
多播路由器不转发以这些地址为目的地址的数据报

IPv6多播地址

IPv6多播地址的高序字节值为ff
上图给出了把16字节IPv6多播地址映射成6字节以太网地址方法
以太网地址首字节的低序2位标明该地址是一个局部管理的组地址
局部管理属性位意味着不能保证该地址对IPv6的唯一性
可能有IPv6以外的其他协议族共享同一网络并使用同样的以太网地址高序2字节值


IPv6多播地址定义有两种格式
当P标志为0时,
T标志区分众所周知多播组[值为0]还是临时多播组[值为1]
P标志为1表示多播地址是基于某个单播前缀赋予的
P标志为1时,T标志也需为1
plen和prefix分别设为前缀长度,单播前缀的值
4位标志字段的高2位保留
IPv6多播地址还有一个4位范围字段

多播

下面是若干特殊的IPv6多播地址
- ff01::1和ff02::1
是所有节点组
子网上所有有多播能力的节点[主机,路由器,打印机等]
必须在所有具有多播能力的接口上加入该组
- ff01::2和ff02::2和ff05::2是所有路由器组
子网上所有多播路由器必须在所有具有多播能力的接口上加入该组

多播地址的范围

IPv6多播地址显式存在一个4位的范围字段
用于指定多播数据报能游走的范围
IPv6还有一个跳限字段,用于限制分组被路由转发的次数
以下为若干已经分配给范围字段的值:
- 接口局部的
- 链路局部的
- 管区局部的
- 网点局部的
- 组织机构局部的
- 全球或全局的
其余值或者不分配,或者保留
接口局部数据报不准由接口输出
链路局部数据报不可由路由器转发
管区,网点,组织机构的具体定义由该网店或组织机构的多播路由器管理员决定

IPv4多播数据报没单独的范围字段
IPv4首部的TTL字段兼用作广播范围字段
0:接口局部
1:链路局部
2~23:网点局部
33~64:地区局部
65~128:大洲局部
129~255:无范围限制

把IPv4的TTL字段用作多播范围控制已被接受且是受推荐的做法,
如可能,可管理的范围划分更为可取.
这样会把IPv4介于239.0.0.0到239.255.255.255
之间的地址定义为可管理地划分范围的IPv4多播空间
它占据多播地址空间的高端

任何组织结构必须把它的边界多播路由器配置成禁止转发以这些地址为目的地址的多播数据报
可管理地划分范围的IPv4多播地址空间被进一步划分为本地范围和组织机构局部范围

多播

多播会话

流式媒体应用中,一个多播地址和一个传输层端口[通常是UDP端口]的组合称为一个会话.
举例:

局域网上多播和广播的比较

多播

上图没展示的3个情形
- 运行所加入多播地址为255.0.1.1的某个应用进程的一个主机
多播地址组ID的高5位在到以太网地址的映射中被忽略
该主机的接口也将接收目的以太网地址为01:00:5e:00:01:01的帧
此时,有该帧承载的分组将由IP层中的完备过滤丢弃
- 运行所加入多播地址符合以下条件的某个应用进程的一个主机:
由这多播地址映射成的以太网地址恰好和01:00:5e:00:01:01一样被该主机执行非完备过滤的接口散列到同一结果.
该接口也将接收目的以太网地址为01:00:5e:00:01:01的帧
直到由数据链路层或IP层丢弃
- 目的地为相同多播组[224.0.1.1]不同端口的一个数据报
右侧主机仍接收该数据报,且由IP层接受并传递给UDP层

广域网上的多播

设5个主机上启动了某个程序
且这5个程序加入了一个给定多播组
设每个多播路由器与其邻居多播路由器的通信使用某个多播路由协议[MRP]

多播

当某个主机上的一个进程加入一个多播组时,
该主机向所有直接连接的多播路由器发送一个IGMP消息
告知它们本主机已加入某多播组
多播路由器随后用MRP交换这些信息
每个多播路由器知道在收到目的地为所加入多播地址的分组时该如何处理

设左上方主机上的一个进程开始发送目的地为那个给定多播地址的分组
比如,这个进程发送的是那些多播接收进程正等着接收的音频分组

多播

可跟踪这些多播分组从发送进程游走到所有接收进程所经历的步骤
- 这些分组在左上方局域网上由发送进程多播发送
接收主机H1接收这些分组[它已经加入给定多播组]
多播路由器MR1也接收这些分组[每个多播路由器都必须接收所有多播分组]
- MR1把这些多播分组转发到MR2
MR2已经通告MR1:MR2需接收目的地为给定多播组的分组
- MR2在直接连接的局域网上多播发送这些分组
该局域网上的主机H2,H3属于该多播组
MR2还向MR3发这些分组的一个副本
- 像MR2对分组进行复制是多播转发所特有的
单播分组被路由器转发时不被复制
- MR3把这些多播分组发到MR4
- MR4在直接连接的局域网上多播发送这些分组
该局域网上的主机H4和H5属于该多播组
它不向MR5发这些分组的一个副本
直接连MR5的局域网上没主机属于该多播组
MR4已经根据与MR5交换的多播路由信息知道此点

源特定多播

广域网的多播因为多个原因,难以部署
运行MRP要求每个多播路由器接收来自所有本地接收主机的多播组加入及其他请求
并在所有多播路由器间交换这些信息

多播路由器的转发功能要求把来自网络中任何发送主机的数据复制并发送到网络中任何接收主机.
IPv4没足够数量的多播地址,可以静态地分配给想用的任何多播应用系统用
要在广域范围发多播分组而又不与其他多播发送进程冲突
多播应用系统就得使用唯一的地址
全球性的多播地址分配机制尚未出现

源特定多播给出了这些问题的一个务实的解决办法
SSM把应用系统的源地址结合到组地址
从而有限程度上如下地解决了这些问题:
- 接收进程向多播路由器提供发送进程的源地址作为多播组加入操作的一部分
可降低多播路由器就每个分组的转发聚散度
每个接收进程都需知道源地址
这样还保留了多播地址的包容性
发送进程无需知道任何进程的地址
- 把多播组的标识从单纯多播组地址细化为单播源地址和多播目的地址之组合
意味着发送进程可挑选任何多播地址
源地址本身往往已经使该组合唯一了
SSM会话由源地址,目的地址,端口三者的组合标识

多播套接字选项

多播
多播

1.IP_ADD_MEMBERSHIP, IPV6_JOIN_GROUP和MCAST_JOIN_GROUP
在一个指定的本地接口上加入一个不限源的多播组
对IPv4,
本地接口使用某个单播地址指定
对IPv6和与协议无关的API
本地接口使用某个接口索引指定
struct ip_mreq
{
	struct in_addr imr_multiaddr;
	struct in_addr imr_interface;
};

struct ipv6_mreq
{
	struct in6_addr ipv6mr_multiaddr;
	unsigned int ipv6mr_interface;
};

struct group_req
{
	unsigned int gr_interface;
	struct sockaddr_storage gr_group;
};
如本地接口指定为IPv4的通配地址
或IPv6值为0的索引
则由内核选一个本地接口
一个主机在某个给定接口上属于一个给定多播组的前提是该主机上当前有一个或多个进程在那个接口上属于该组
在一个给定套接字上可多次加入多播组
不过每次加入的必须是不同的多播地址
或是在不同接口上的同一个多播地址

多次加入可用于多宿主机
如创建一个套接字后对于一个给定多播地址在每个接口上执行一次加入
IPv6多播地址显式存在一个范围字段
仅仅范围有差异的IPv6多播地址代表不同的多播组
如某个NTP实现想要不论范围接收所有NTP分组
就必须加入ff01::101
ff02::101
ff05::101
ff08::101
ff0e::101
所有这些加入都可在单个套接字上执行
且可通过设置IPV6_PKTINFO套接字选项让recvmsg返回每个数据报的目的地址

IP协议无关的套接字选项与IPv6版本几乎相同
差别只是改用一个sockaddr_storage结构代替in6_addr结构传递多播组地址
sockaddr_storage应足以存放系统支持的任何类型的地址

2.IP_DROP_MEMBERSHIP,IPV6_LEAVE_GROUP和MCAST_LEAVE_GROUP
离开指定的本地接口上不限源的多播组
刚才给出的加入不限源多播组所用的结构同样适用于本套接字选项的各种版本
如未指定本地接口,
则抹除首个匹配的多播组成员关系

如一个进程加入某个多播组后从不显式离开该组
则当相应套接字关闭时,
该成员关系自动抹除

单个主机上,可能有多个套接字各自加入相同的多播组
此时,单个套接字成员关系的抹除不影响该主机继续作为多播组的成员,
直到最后一个套接字也离开该多播组
3.IP_BLOCK_SOURCE和MCAST_BLOCK_SOURCE
对一个所指定本地接口上已存在的一个不限源的多播组
在本套接字上阻塞接收来自某个源的多播分组
如加入同一个多播组的所有套接字都阻塞了相同的源
则主机系统可通知多播路由器这种分组流通不再需要
并可能由此影响网络中的多播路由
该套接字选项可用于忽略如来自无赖发送进程的分组流通
对IPv4
本地接口有某个单播地址指定
对与IP协议无关的API
本地接口由某个接口索引指定
struct ip_mreq_source
{
	struct in_addr imr_multiaddr;
	struct in_addr imr_sourceaddr;
	struct in_addr imr_interface;
};

struct group_source_req
{
	unsigned int gsr_interface;
	struct sockaddr_storage gsr_group;
	struct sockaddr_storage gsr_source;
};
如本地接口指定为IPv4的通配地址
或与协议无关的API的0值索引
则就由内核选择与首个匹配的多播组成员关系对应的本地接口
源阻塞请求修改已存在的组成员关系,
必须已使用IP_ADD_MEMBERSHIP
IPV6_JOIN_GROUP
MCAST_JOIN_GROUP
在对应的接口上加入对应的多播组
4.IP_UNBLOCK_SOURCE和MCAST_UNBLOCK_SOURCE
开通一个先前被阻塞的源
如未指定本地接口
则开通首个匹配的被阻塞源
5.IP_ADD_SOURCE_MEMBERSHIP
MCAST_JOIN_SOURCE_GROUP
在一个指定的本地接口上加入一个特定于源的多播组
前面给出的用于阻塞或开通某个源的结构同样适用于本套接字选项的各种版本
在这本地接口上绝不能作为不限源的多播组已经或将要使用IP_ADD_MEMBERSHIP
IPV6_JOIN_GROUP
MCAST_JOIN_GROUP
加入这多播组

如本地接口指定为IPv4的通配地址或与协议无关的API的0值索引
则由内核选一个本地接口
6.IP_DROP_SOURCE_MEMBERSHIP
MCAST_LEAVE_SOURCE_GROUP
在一个指定的本地接口上离开一个特定于源的多播组
刚才给出的用于阻塞或开通某个源的结构同样适用本套接字选项的各个版本