多点通讯与多址广播语义

B.1  多点通讯与多址广播引言

       考虑到如何在 WinSock 2 中支持多点通讯( multipoint )与多址广播( multicast ),我们研究了一些现存的和提议的多点通讯/多址广播方案(包括 IP-multicast ATM 点对多点连接、 ST-II T.120 H.320 (MCU) )。在一些公共方面,每一种方案都与其它方案有很大的不同。为了对不同的方案有一个一致的讨论,首先建立一个分类法来刻画每一种方案的本质属性是很有价值的。为简单起见,在后面我们将使用术语多点通讯来表示多点通讯与多址广播。

B.2   多点通讯分类法

       本附录中描述的分类法首先区别只关心用来建立多点通讯会话的方法本身的控制平面( control plane )和处理在会话参与者之间传送数据的数据平面( data plane )。

       在控制平面,有两种截然不同的会话建立类型: rooted (有根)和 non-rooted (无根)。在 rooted 控制中,有一个特殊的参与者 c_root (根节点),它和多点通讯会话中的其它成员(叶子节点,叫 c_leaf )都不同。 c_root 必须在整个多点通讯会话期都存在,如果 c_root 缺席则会话将被中断。通常情况下, c_root 通过与一个或一组 c_leaf 节点建立连接来初始化多点通讯会话。 c_root 可以增加多个 c_leaf ,或者在某些情形下可以由 c_leaf 稍后加入 c_root Rooted 控制平面可以在 ATM ST-II 的多点通讯方案中找到。

       non-rooted 控制平面中,从属于一个多点通讯会话的所有成员都是叶子节点,也就是说,没有象 c_root 这样的特殊参与者存在。每一个 c_leaf 需要将自己加入到一个预先存在的会话,该会话总是可用的(象 IP multicast 地址)或者是通过一种不在 WinSock 规范范围内描述的带外机制来建立。也可以用另一种方法来看这个问题,即 c_root 总是存在的,它作为一个参与者隐藏在网络云团( network cloud )中。由于控制根节点的存在,一个 non-rooted 控制平面也可以被认为是隐含的有根的。这种隐含有根多点通讯方案的例子是:一个电话会议桥、 IP multicast 系统、 H.320 电视会议中的一个多点通讯控制单元( MCU )等。

       在数据平面,有两种类型的数据传送风格: rooted non-rooted 。在 rooted 数据平面,存在一个特殊的参与者 d_root (根节点)。数据传送只能在 d_root 和该多点通讯会话中的其它成员(叶子节点,叫 d_leaf )之间发生。通信可以是单向的也可以是双向的。 d_root 节点发送的数据将被复制(如果需要)并递送到每一个 d_leaf 节点,但从 d_leaf 节点发送的数据只递送到 d_root 节点。在这种有根数据平面中, d_leaf 节点之间不允许有通信。这样的协议例子是 ST-II

       non-rooted 数据平面中,所有参与者是平等的,它们发送的数据将被递送到同一多点通讯会话中的所有参与者。同样地,每一个 d_leaf 节点都能够接收到所有其它 d_leaf 节点发送的数据,并且在一些情形下,还能够接收那些不参与此多点通讯会话的其它节点发送的数据。在 non-rooted 数据平面没有特殊的 d_root 节点存在。 IP-multicast 是无根的数据平面。

       注意,象数据单元复制在哪儿发生、是使用共享的单个树还是使用多个最短路径树来做多点通讯发布这些问题都是协议问题,它们与应用程序用来执行多点通讯通信的接口不相关。因此,这些问题在本附录和 WinSock 接口中都不涉及。

       B.1 描述了上面讲的分类法,并指出了每一种类别相适应的现存的方案。注意不是所有采用 non-rooted 控制平面的现存方案都使用 rooted 数据平面。

B.1  多点通讯分类

 

rooted 控制平面

non-rooted 控制平面 ( 隐含 rooted)

rooted 数据平面

ATM ST-II

没有已知的例子

non-rooted 数据平面

T.120

IP-multicast H.320 (MCU)

B.3   WinSock 2 的多点通讯与多址广播接口元素

       为了使用多点通讯能力而组合到 WinSock 2 中的机制可以归纳如下:

·         WSAPROTOCOL_INFO 结构中的三个属性位;

·         WSASocket() 函数的参数 dwFlags 定义的四个标志;

·         为在一个多点通讯会话中增加叶子节点而设置的一个函数 WSAJoinLeaf()

·         为控制多点通讯内部回送( loopback )与多址广播传播范围而设置的 WSAIoctl() 函数的两个命令码。

下面的段落将详细描述这些接口元素。

B.3.1  WSAPROTOCOL_INFO 结构中的属性

       为了支持上面的分类法,在结构 WSAPROTOCOL_INFO 中使用了三个属性域来分别区分使用控制平面和数据平面的不同方案:

1)        XP1_SUPPORT_MULTIPOINT 值为 1 时指示此协议入口支持多点通讯通信,并指示下面的两个域有意义。

2)        XP1_MULTIPOINT_CONTROL_PLANE 指示控制平面是有根的( rooted ,值为 1 )还是无根的( non-rooted ,值为 0 )。

3)        XP1_MULTIPOINT_DATA_PLANE 指示数据平面是有根的( rooted ,值为 1 )还是无根的( non-rooted ,值为 0 )。

       注意,如果一个多点通讯协议同时支持 rooted non-rooted 数据平面,则要使用两个 WSAPROTOCOL_INFO 入口,每一个数据平面一个入口。

       应用程序可以使用 WSAEnumProtocols() 函数来检测一个给定的协议是否支持多点通讯通信,如果支持,它是如何分别支持控制平面与数据平面的。

B.3.2  WSASocket() 函数使用的标志

       在一些实例中,加入到多点通讯会话中的套接字具有和点对点通信的套接字不同的一些行为。例如,在 rooted 数据平面中的 d_leaf 套接字只能发送信息给 d_root 参与者。这对应用程序产生了一个需求,即它要能够指示对套接字的这种使用与创建一致。这通过在 WSASocket() 函数的参数 dwFlags 中使用四个标志位来实现:

·         WSA_FLAG_MULTIPOINT_C_ROOT ,用来创建一个作为 c_root 节点的套接字,并且只有在相应的 WSAPROTOCOL_INFO 入口中指示了使用 rooted 控制平面时才允许。

·         WSA_FLAG_MULTIPOINT_C_LEAF ,用来创建一个作为 c_leaf 节点的套接字,并且只有在相应的 WSAPROTOCOL_INFO 入口中指示了 XP1_SUPPORT_MULTIPOINT 时才允许。

·         WSA_FLAG_MULTIPOINT_D_ROOT ,用来创建一个作为 d_root 节点的套接字,并且只有在相应的 WSAPROTOCOL_INFO 入口中指示了使用 rooted 数据平面时才允许。

·         WSA_FLAG_MULTIPOINT_D_LEAF ,用来创建一个作为 d_leaf 节点的套接字,并且只有在相应的 WSAPROTOCOL_INFO 入口中指示了 XP1_SUPPORT_MULTIPOINT 时才允许。

       注意,当创建一个多点通讯套接字时,必须精确地使用两个控制平面标志位中的一个和两个数据平面标志位中的一个的“或”来作为 WSASocket() 函数的 dwFlags 参数。因此,创建多点通讯套接字有四种可能性:“ c_root/d_root ”、“ c_root/d_leaf ”、“ c_leaf/d_root ”或“ c_leaf /d_leaf ”。

B.3.3  WSAIoctl() 函数的 SIO_MULTIPOINT_LOOP 命令码

       d_leaf 套接字用于 non-rooted 数据平面时,它通常是希望能够控制发送出去的通信流量是否能够在同一个套接字上也被接收。 WSAIoctl() 函数的 SIO_MULTIPOINT_LOOP 命令码用来允许或禁止多点通讯的通信流量的内部回送。

B.3.4  WSAIoctl() 函数的 SIO_MULTICAST_SCOPE 命令码

       当使用多址广播时,常常需要指定多址广播传播的范围。范围由包括的路由网段来定义。范围为 0 指示多址广播不传播信息到“网线”上,但是可以在本地主机的多个套接字间传播。范围为 1 (默认值)指示将传播信息到“网线”上,但是不跨越路由器。更高的范围值决定了可以跨越的路由器数量。注意这相当于 IP multicast 中的生存时间( time-to-live TTL )。

B.3.5  WSAJoinLeaf()

       此函数用来加入一个叶子节点到多点通讯会话,其函数原型为:

SOCKET WSAAPI WSAJoinLeaf ( SOCKET s , const struct sockaddr FAR * name , int namelen , LPWSABUF lpCallerData , LPWSABUF lpCalleeData , LPQOS lpSQOS , LPQOS lpGQOS , DWORD dwFlags );

       详细情况参见后面关于如何使用此函数的讨论。

B.4  加入多点通讯叶子节点的语义

       在后面的叙述中,多点通讯套接字常常被定义在两个平面(控制或数据)之一上。但是,应该理解此套接字也在另一个平面上扮演相同角色,而为了述说的简短,这在后面将不再提及。例如,当说到建立一个“ c_root 套接字”时,它可能是一个 c_root/d_root 套接字,也可能是一个 c_root/d_leaf 套接字。

       rooted 控制平面方案中,新的叶子节点加入到多点通讯会话中可以采用两种不同方法中的一种或全部。第一种方法,根节点使用 WSAJoinLeaf() 函数来初始化与一个叶子节点的连接,同时邀请其成为参与者。在叶子节点方面,对等的应用程序必须已经创建了一个 c_leaf 套接字并使用 listen() 函数设置其处于监听模式。当被邀请加入会话时,叶子节点将接收到一个 FD_ACCEPT 指示,并通过调用 WSAAccept() 函数自动加入会话。在加入操作完成后,根节点应用程序将接收到 FD_CONNECT 指示。

       在第二种方法中,角色本质上反了过来。根节点应用程序创建一个 c_root 套接字并设置其处于监听模式。希望加入会话的叶子节点创建一个 c_leaf 套接字并使用 WSAJoinLeaf() 函数来初始化连接并请求准入。根应用程序在外来的准入请求到达时接收到一个 FD_ACCEPT 指示,并通过调用 WSAAccept() 函数接纳叶子节点。当被接纳时,叶子节点接收到 FD_CONNECT 指示。

       在一个 non-rooted 控制平面中,所有的节点都是 c_leaf WSAJoinLeaf() 函数被用来将一个节点加入到现存的多点通讯会话中。当加入完成后将提供 FD_CONNECT 指示,并返回用于多点通讯会话中的套接字描述符。在 IP multicast 中,这与 IP_ADD_MEMBERSHIP 套接字选项一致。

       因此,有三种场合应用程序将使用 WSAJoinLeaf() 函数:

1)         作为多点通讯根节点并邀请一个新的叶子节点加入会话;

2)         作为一个叶子节点向一个有根多点通讯会话提出准入请求;

3)         作为一个叶子节点向无根多点通讯会话寻求准入(如 IP multicast )。

B.4.1  使用 WSAJoinLeaf()

       正如前面提到的,函数 WSAJoinLeaf() 被用来加入一个叶子节点到多点通讯会话中。 WSAJoinLeaf() 具有与 WSAConnect() 相同的参数和语法,除了它还返回一个套接字描述符(这和函数 WSAAccept() 一样)及多了一个 dwFlags 参数外。参数 dwFlags 用来指示套接字是用来作为发送者还是接收者还是两者兼具。在此函数中,只有多点通讯套接字可以用来作为输入参数 s 。如果此多点通讯套接字处于非阻塞模式,返回的套接字描述符只有在接收到相应的 FD_CONNECT 指示后才能使用。多点通讯会话中的根应用程序可以调用 WSAJoinLeaf() 函数一次或多次以加入一组叶子节点,然而,绝大多数情形下一个多点通讯连接请求每次都可能是未完成的( outstanding )。

       函数 WSAJoinLeaf() 返回的套接字描述符因输入套接字描述符 s c_root 还是 c_leaf 有所不同。当使用 c_root 套接字时,参数 name 指示要加入的一个特定叶子节点,返回的套接字描述符是一个对应新增加的叶子节点的 c_leaf 套接字。此套接字不推荐用来交换多点通讯数据,但是可以用来接收特定 c_leaf 连接的 FD_XXX 网络事件指示(如 FD_CLOSE )。一些多点通讯实现也允许此套接字用来在 root 和单个叶子节点之间交流。如果相应的叶子节点调用 closesocket() 函数退出多点通讯会话,则此函数将受到一个 FD_CLOSE 指示。对称地,在 WSAJoinLeaf() 函数返回的 c_leaf 套接字上执行 closesocket() 函数将引起相应叶子节点上的套接字得到 FD_CLOSE 通知。

       当函数 WSAJoinLeaf() c_leaf 套接字上执行,参数 name 包含了 root 应用程序的地址(对于有根控制方案)或一个存在的多点通讯会话(对于非根控制方案),返回的套接字描述符和输入的套接字描述符相同。在一个有根控制方案中, root 应用程序通过使用 listen() 函数使 c_root 套接字处于监听模式,当叶子节点请求将自己加入多点通讯会话时 c_root 套接字将接收到标准的 FD_ACCEPT 通知。 root 应用程序通常使用 accept()/WSAAccept() 函数来接纳新叶子节点。无论是 accept() 还是 WSAAccept() 函数的返回值都是一个 c_leaf 套接字描述符,如同函数 WSAJoinLeaf() 返回的一样。为了适应同时允许根初始化加入和叶子初始化加入的多点通讯方案,对于已经处于监听模式的 c_root 套接字来说,使用它作为函数 WSAJoinLeaf() 的输入也是可以接受的。

       一个多点通讯的 root 应用程序通常应该负责有序地撤除多点通讯会话。这样的应用程序可以在 c_root 套接字上使用 shutdown() closesocket() 函数来促使所有的相关 c_leaf 套接字,包括那些由 WSAJoinLeaf() 函数返回的套接字及它们对应的远程叶子节点上的 c_leaf 套接字,都得到 FD_CLOSE 通知。

B.5  多点通讯套接字与常规套接字之间的语义差别

       在控制平面中, c_root 套接字和常规点对点套接字之间在一些重要语义上有区别:

1)         c_root 套接字可以用于 WSAJoinLeaf() 函数以加入一个新的叶子节点;

2)         使用 listen() 函数设置一个 c_root 套接字处于监听模式并不排除该 c_root 套接字用于 WSAJoinLeaf() 函数以加入一个新的叶子节点,也不排除该 c_root 套接字用于发送和接收多点通讯数据。

3)         关闭 c_root 套接字将导致所有相关联的 c_leaf 套接字都得到 FD_CLOSE 通知。

       在控制平面中, c_leaf 套接字和常规套接字没有语义上的区别,只不过 c_leaf 套接字可以用于 WSAJoinLeaf() 函数,并且 c_leaf 套接字用于 listen() 函数指示只有多点通讯连接请求应该被接收。

       在数据平面中, d_root 套接字和常规点对点套接字的语义区别为:

1)        d_root 套接字上发送的数据将被递送到同一多点通讯会话中的所有叶子节点;

2)        d_root 套接字上接收的数据可以来自任何叶子节点。

       在有根数据平面中, d_leaf 套接字和常规套接字没有语义上的区别,然而,在非根数据平面中,在 d_leaf 套接字发送的数据将传播到所有其它叶子节点,并且接收的数据可能来自任何其它叶子节点。正如前面已经提到,关于 d_leaf 套接字是在有根还是在非根数据平面的信息包含在套接字相应的 WSAPROTOCOL_INFO 结构中。

B.6  现存的多点通讯协议如何支持这些扩展

       在本节,我们将简要说明 IP multicast ATM 点对多点通讯能力是如何通过 WinSock 2 的多点通讯函数来访问的。我们选择这两种协议来做例子是因为它们使用得非常普遍并且较好理解。

B.6.1  IP multicast

       IP multicast 属于 non-rooted 数据平面与 non-rooted 控制平面这一类。所有的应用程序都起叶子节点的作用。现在绝大多数 IP multicast 实现都使用 Steve Deering IETF 提议的套接字选项集合。这种方案有五种操作可用:

·         IP_MULTICAST_TTL :设置生存时间,控制多址广播会话范围;

·         IP_MULTICAST_IF :确定接口用于多址广播;

·         IP_ADD_MEMBERSHIP :加入一个指定的多址广播会话;

·         IP_DROP_MEMBERSHIP :离开多址广播会话;

·         IP_MULTICAST_LOOP :控制多址广播信息流量的内部回送。

       IP multicast 套接字设置生存时间可以直接使用 WSAIoctl() 函数的命令码 SIO_MULTICAST_SCOPE ,确定 IP 接口用于多址广播的方法是通过特定的 TCP/IP 实现的套接字选项,这在 WinSock 2 的特定协议附件( WinSock 2 Protocol Specific Annex )中描述。

       剩下的三个操作在下面描述的 WinSock 2 语义中有很好的介绍。应用程序调用 WSASocket() 函数打开套接字时使用 c_leaf/d_leaf 标志,并调用 WSAJoinLeaf() 函数将自己加入到默认的多址广播操作接口上的一个多址广播组中。如果在 WSAJoinLeaf() 函数中的标志指示此套接字只是一个发送者,那么加入操作本质上将没有做任何操作并且不必发送任何 IGMP 消息。否则,将发送一个 IGMP 包给路由器,指示该节点有兴趣接收发送到指定的多址广播地址上的包。既然应用程序创建了专门的 c_leaf/d_leaf 套接字用于执行多址广播,因此标准的 closesocket() 函数可以用来离开多址广播会话。 WSAIoctl() 函数的命令码 SIO_MULTIPOINT_LOOP 提供了一种通用的控制机制来决定在 non-rooted 多点通讯方案中的 d_leaf 套接字上发送的数据是否也被同一套接字接收。

B.6.2  ATM 点对多点通信

       ATM 属于 rooted 数据平面与 rooted 控制平面这一类。一个作为 root 的应用程序创建 c_root 套接字,与之相对应的应用程序是在叶子节点上运行,使用的是 c_leaf 套接字。 root 应用程序使用 WSAJoinLeaf() 来加入叶子节点,叶子节点上相应的应用程序设置它们的 c_leaf 套接字处于监听模式。指定 c_root 套接字的 WSAJoinLeaf() 函数被映射到 Q.2931 ADDPARTY 消息。由叶子节点发动的加入操作不被 ATM UNI 3.1 支持,但在 ATM UNI 4.0 中得到支持。因此,指定 c_leaf 套接字的 WSAJoinLeaf() 函数被映射到适当的 ATM UNI 4.0 消息。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值