打印

关于多播我有话说

[复制链接]
1973|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
6019赵文|  楼主 | 2011-6-16 15:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1、区分多播和多播的区别
单播、多播、广播、组播、泛播、冲突域、广播域定义及特点
假设X代表所有的机器,Y代表X中的一部分机器,Z代表一组机器,1代表一台机器,那么
1:1 那就是单播;
1:Y 那就是多播;
1:X 那就是广播;
1:Z 那就是组播;
Y=X时,多播就是广播;Y=Z多播就是组播;


泛播也叫任意播,是指某组中任意发送方对应拓朴结构中几个最接近的接收方之间的通信。
而组播是指单个发送方对应一组选定接收方的一种通信。

一、什么是组播
1、组播的特点
1)什么是组播?
组播是一种数据包传输方式,当有多台主机同时成为一个数据包的接受者时,出于对带宽和CPU负担的考虑,组播成为了一种最佳选择。
2)组播如何进行工作?
    组播通过把224.0.0.0-239.255.255.255的D类地址作为目的地址,有一台源主机发出目的地址是以上范围组播地址的报文,在网络中,如果有其他主机对于这个组的报文有兴趣的,可以申请加入这个组,并可以接受这个组,而其他不是这个组的成员是无法接受到这个组的报文的。
3)组播和单播的区别?
   为了让网络中的多个主机可以同时接受到相同的报文,如果采用单播的方式,那么源主机必须不停的产生多个相同的报文来进行发送,对于一些对时延很敏感的数据,在源主机要产生多个相同的数据报文后,在产生第二个数据报文,这通常是无法容忍的。而且对于一台主机来说,同时不停的产生一个报文来说也是一个很大的负担。如果采用组播的方式,源主机可以只需要发送一个报文就可以到达每个需要接受的主机上,这中间还要取决于路由器对组员和组关系的维护和选择。
4)组播和广播的区别?
   如同上个例子,当有多台主机想要接收相同的报文,广播采用的方式是把报文传送到局域网内每个主机上,不管这个主机是否对报文感兴趣。这样做就会造成了带宽的浪费和主机的资源浪费。而组播有一套对组员和组之间关系维护的机制,可以明确的知道在某个子网中,是否有主机对这类组播报文感兴趣,如果没有就不会把报文进行转发,并会通知上游路由器不要再转发这类报文到下游路由器上。
2、组播的缺点:
1) 与单播协议相比没有纠错机制,发生丢包错包后难以弥补,但可以通过一定的容错机制和QOS加以弥补。
2) 现行网络虽然都支持组播的传输,但在客户认证、QOS等方面还需要完善,这些缺点在理论上都有成熟的解决方案,只是需要逐步推广应用到现存网络当中。
二、单播:
1、单播的定义
    主机之间“一对一”的通讯模式,网络中的交换机和路由器对数据只进行转发不进行复制。如果10个客户机需要相同的数据,则服务器需要逐一传送,重复10次相同的工作。但由于其能够针对每个客户的及时响应,所以现在的网页浏览全部都是采用IP单播协议。网络中的路由器和交换机根据其目标地址选择传输路径,将 IP单播数据传送到其指定的目的地。
2、单播的优点:
1)服务器及时响应客户机的请求
2)服务器针对每个客户不通的请求发送不通的数据,容易实现个性化服务。
3、单播的缺点:
1)服务器针对每个客户机发送数据流,服务器流量=客户机数量×客户机流量;在客户数量大、每个客户机流量大的流媒体应用中服务器不堪重负。
2)现有的网络带宽是金字塔结构,城际省际主干带宽仅仅相当于其所有用户带宽之和的5%。如果全部使用单播协议,将造成网络主干不堪重负。现在的P2P应用就已经使主干经常阻塞,只要有5%的客户在全速使用网络,其他人就不要玩了。而将主干扩展20倍几乎是不可能。
三、 广播
1、广播的定义
主机之间“一对所有”的通讯模式,网络对其中每一台主机发出的信号都进行无条件复制并转发,所有主机都可以接收到所有信息(不管你是否需要),由于其不用路径选择,所以其网络成本可以很低廉。有线电视网就是典型的广播型网络,我们的电视机实际上是接受到所有频道的信号,但只将一个频道的信号还原成画面。在数据网络中也允许广播的存在,但其被限制在二层交换机的局域网范围内,禁止广播数据穿过路由器,防止广播数据影响大面积的主机。
2、广播的优点:
1)网络设备简单,维护简单,布网成本低廉
2)由于服务器不用向每个客户机单独发送数据,所以服务器流量负载极低。
3、广播的缺点:
1)无法针对每个客户的要求和时间及时提供个性化服务。
2)网络允许服务器提供数据的带宽有限,客户端的最大带宽=服务总带宽。例如有线电视的客户端的线路支持100个频道(如果采用数字压缩技术,理论上可以提供 500个频道),即使服务商有更大的财力配置更多的发送设备、改成光纤主干,也无法超过此极限。也就是说无法向众多客户提供更多样化、更加个性化的服务。
3) 广播禁止在Internet宽带网上传输。

四、多播
1、多播的定义
“多播”可以理解为一个人向多个人(但不是在场的所有人)说话,这样能够提高通话的效率。如果你要通知特定的某些人同一件事情,但是又不想让其他人知道,使用电话一个一个地通知就非常麻烦,而使用日常生活的大喇叭进行广播通知,就达不到只通知个别人的目的了,此时使用“多播” 来实现就会非常方便快捷,但是现实生活中多播设备非常少。多播包括组播和广播,组播是多播的一种表现形式。
2、多播的特点
    广播和多播仅应用于UDP,它们对需将报文同时传往多个接收者的应用来说十分重要。TCP是一个面向连接的协议,它意味着分别运行于两主机(由IP地址确定)内的两进程(由端口号确定)间存在一条连接。
   考虑包含多个主机的共享信道网络如以太网。每个以太网帧包含源主机和目的主机的以太网地址(48 bit)。通常每个以太网帧仅发往单个目的主机,目的地址指明单个接收接口,因而称为单播(unicast)。在这种方式下,任意两个主机的通信不会干扰网内其他主机(可能引起争夺共享信道的情况除外)。然而,有时一个主机要向网上的所有其他主机发送帧,这就是广播。通过ARP和RARP可以看到这一过程。多播(multicast) 处于单播和广播之间:帧仅传送给属于多播组的多个主机。

五、泛洪
1、泛洪的定义
在CISCO设备上有个概念叫泛洪。如果有学设备的,我这里顺便对比讲下,比如现在有个信息包进来,从我们交换机某个端口进来,他要寻质如果事先没有地址那么他就会给每个端口发信息,包括自己,来求证是否是对方。所以交换机不能屏蔽广播而路由器可以,因为他有**功能,可以形成路由表。而设备上的泛洪呢他的意思是给所有端口发除了自己,大家对记下这两个概念.而我们IP地址上的广播地址的概念:IP地址是由2进制组成,当全为一时,表示广播地址。广播地址主机都为1.主机全为0的话是网段表示一个网。
2、网络泛洪
从定义上说,攻击者对网络资源发送过量数据时就发生了洪水攻击,这个网络资源可以是router,switch,host,application等。常见的洪水攻击包含MAC泛洪,网络泛洪,TCP SYN泛洪和应用程序泛洪。接下来简单的分别解释一下以上这些:
    1)MAC泛洪发生在OSI第二层,攻击者进入LAN内,将假冒源MAC地址和目的MAC地址将数据帧发送到以太网上导致交换机的内容可寻址存储器(CAM)满掉,然后交换机失去转发功能,导致攻击者可以像在共享式以太网上对某些帧进行嗅探,这种攻击可以通过端口安全技术方式,比如端口和MAC地址绑定。
    2)网络泛洪包括Smurf和DDos:
    smurf发生在OSI第三层,就是假冒ICMP广播ping,如果路由器没有关闭定向广播,那攻击者就可以在某个网络内对其它网络发送定向广播 ping,那个网络中的主机越是多,造成的结果越是严重,因为每个主机默认都会响应这个ping,导致链路流量过大而拒绝服务,所以属于增幅泛洪攻击,当然也可以对本            网络发送广播ping。
    3)DDos发生在OSI第三、四层,攻击侵入许多因特网上的系统,将DDos控制软件安装进去,然后这些系统再去感染其它系统,通过这些代理,攻击者将攻击指令发送给DDos控制软件,然后这个系统就去控制下面的代理系统去对某个IP地址发送大量假冒的网络流量,然后受攻击者的网络将被这些假的流量所占据就无法为他们的正常用户提供服务了。
    4)TCP SYN泛洪发生在OSI第四层,这种方式利用TCP协议的特性,就是三次握手。攻击者发送TCP SYN,SYN是TCP三次握手中的第一个数据包,而当服务器返回ACK后,改攻击者就不对之进行再确认,那这个TCP连接就处于挂起状态,也就是所谓的半连接状态,服务器收不到再确认的话,还会重复发送ACK给攻击者。这样更加会浪费服务器的资源。攻击者就对服务器发送非常大量的这种TCP连接,由于每一个都没法完成三次握手,所以在服务器上,这些TCP连接会因为挂起状态而消耗CPU和内存,最后服务器可能死机,就无法为正常用户提供服务了。
    5)最后应用程序泛洪发生在OSI第七层,目的是消耗应用程序或系统资源,比较常见的应用程序泛洪是什么呢?没错,就是垃圾邮件,但一般无法产生严重的结果。其它类型的应用程序泛洪可能是在服务器上持续运行高CPU消耗的程序或者用持续不断的认证请求对服务器进行泛洪攻击,意思就是当TCP连接完成后,在服务器提示输入密码的时候停止响应。

冲突域(物理分段):连接在同一导线上的所有工作站的集合,或者说是同一物理网段上所有节点的集合或以太网上竞争同一带宽的节点集合。也就是说,用Hub或者Repeater连接的所有节点可以被认为是在同一个冲突域内,它不会划分冲突域。由于广播域被认为是OSI中的第二层概念,所以象 Hub,交换机等第一,第二层设备连接的节点被认为都是在同一个广播域。

冲突域(Collision Domain):一组与同一条物理介质相连的设备,其中任何两台设备同时访问该介质都将导致冲突,冲突域中同一时间内只有一台机器能够发送数据。
广播域(Broadcast Domain):网络中一组相互接收广播消息的设备。

第一层设备如集线器,与之连接的所有设备都属于同一个冲突域和同一个广播域;
第二层设备如交换机和网桥,将网络划分成多个网段,每个网段是一个独立的冲突域,但是相连的所有设备是一个广播域,交换机的每个端口就是一个冲突域;
第三层设备如路由器,将网络划分为多个冲突域和广播域。
以太网使用载波侦听多路访问/冲突检测(Carrier Sense Multi-Access/Collision Detection)技术以减少冲突的发生。
即,二层广播帧覆盖的范围就是广播域;二层单播帧覆盖的范围就是冲突域。
总结一下:
多点传送(多播):一对多个

直接广播(广播):一对所有

单点传送(单播):一对一
个单播的区别

相关帖子

沙发
6019赵文|  楼主 | 2011-6-16 15:04 | 只看该作者
终于找到关于RTL8019AS里的 MAR0-MAR7的计算的程序,源程序是80x86的汇编,我把它转换成了在keil c51里的程序,以便可以在51单片机里使用。

跟组播地址有关的寄存器:

为8个寄存器,提供对组播地址的过滤。跟crc的逻辑有关。MAR0-7 全部设置为0xff时,将接收所有的组播数据包,将MAR0-7 全部设置为0x00时,将不接收所有组播地址的数据包。在windows98里,该值被设置为:
MAR0=0x00;
MAR1=0x41;
MAR2=0x00;
MAR3=0x80;
MAR4=0x00;
MAR5=0x00;
MAR6=0x00;
MAR7=0x00;

用户在嵌入式的应用当中,可以设置为全部0xff,也可以对特定的组播地址(比如你用在网络电台广播)进行计算,生成一个你需要的过滤参数。建议该过滤的算法不写在单片机里,最好是先算好,存储在单片机里,用的时候直接调用,以节省单片机的程序空间。


这8个寄存器的值是根据组播地址数组的值生成的,提供对组播地址的过滤,过滤掉一些不属于自己接收组播数据包。
以下是在80x86 里的汇编程序:
点击这里打开
;注解: laogu  http://www.laogu.com
;这是一段在80x86里的汇编源程序,用来生成多播地址过滤的 MAR0-MAR7(以太网卡里的多播地址过滤寄存器)
;多播也叫组播。程序调用的时候 将组播地址列表的地址传递到ds:si ,
;列表相当于c语言里的二维数组 unsigned char multicast_addresses[ax][6];
;   因为每个地址的长度为6,总共有ax个组播地址。
; ds:si 相当于c语言里的指针 unsigned char *multicast_addresses ;
;将地址总数传递到ax,字节数(=地址总数*6)传递到 cx里(在这个程序里,没有用到cx传递的值)

;程序运算的结果放在mcast_list_bits里,相当于c语言里的unsigned char mcast_list_bits[8];
;程序里的di相当于c语言里的指针 unsigned char *mcast_list_bits;
;mcast_list_bits[8]对应于地址过滤寄存器MAR[8],即MAR0---MAR7
;函数 set_hw_multi ; Set the multicast mask bits in chip是将mcast_list_bits[8]写入到MAR0--MAR7
;的一个函数调用,这里没有写。
    public   set_multicast_list
set_multicast_list:
;enter with ds:si ->list of multicast addresses, ax = number of addresses,
;  cx = number of bytes.
;入口调用: 将list of multicast addresses 组播地址列表(可以有多个组播地址)的地址放在
;ds:si  指针里。ax为多播地址的个数。cx为字节数
;return nc if we set all of them, or cy,dh=error if we didn't.
;设置成功返回c=0,失败c=1(c就是cy,cpu标志位)
    assume ds:code
    mov   cx,ax       ;keep a count of addresses in cx.
           ;cx=多播地址的个数
    mov   di,offset mcast_list_bits ;di=64位的多播地址crc
    xor   ax,ax
    mov   [di+0],ax
    mov   [di+2],ax
    mov   [di+4],ax
    mov   [di+6],ax   ;将多播地址8个字节的crc全部设置为0
    jcxz  set_mcl_2   ;cx=0 跳到set_mc1_2,将多播地址crc设置为全部0
set_mcl_1:
    call  add_mc_bits  ;调用crc计算
    loop  set_mcl_1
set_mcl_2:
    call    set_hw_multi ; Set the multicast mask bits in chip
                            ;将mcast_list_bits[8]  8个字节分别写入到MAR0--MAR7
                            ;mcast_list_bits[0]对应于MAR0   .
    clc
    ret
;=================
add_mc_bits:  开始计算
;entry:   ds:si -> multicast address, di-> sixty-four bit multicast filter.
;preserve cx, di, increment si by EADDR_LEN
    push  cx ;保存cx,就是保存多播地址的个数
    mov   cx,EADDR_LEN  ;EADDR_LEN就是以太网地址的长度=6
    mov   dx,0ffffh         ; this is msw.
    mov   bx,0ffffh         ; set 32 bit number
add_mcb_1:
    lodsb  ;将一个字节的数(地址为si指向的数)装到AL里,同时使si地址+1
    call  upd_crc        ; update crc
    loop  add_mcb_1      ; and loop.
;=============
  ifdef MULTICRC_REVERSE  ;ifdef 到endif这段函数是产生CRC过滤的反顺序码的,
                          ;例如 0000001 反顺序就是 1000000
                          ;就是高位和低位反过来。
                          ;程序的执行将dh里的数反顺序排列
                          ;这段程序应该是没有使用,也就是说我们用的是正顺序码。而不是反顺序码。
    mov   cl,8
add_mcb_2:
    shl   dh,1    ;逻辑左移1位,高位进c,地位补0
    rcr   dl,1       ;带进位的循环右移,c进高位,低位进c
    loop  add_mcb_2
    mov   dh,dl
  endif
;====================
    mov   al,dh       ; get ms 8 bits,
    rol   al,1     ;循环左移,高位进c和低位,
    rol   al,1
    rol   al,1        ; put 3 bits at bottom
    and   al,7
    mov   bl,al       ; save in bl
    xor   bh,bh       ; make bx into an index to the byte.
    mov   al,dh       ; get ms 8 bits,
    ror   al,1         ;循环右移,低位进c和高位
    ror   al,1        ; but at bottom
    and   al,7
    mov   cl,al       ; save in cl
    mov   al,1
    shl   al,cl       ; set the correct bit,
   
                     ;逻辑左移1位,高位进c,地位补0
    or [bx+di],al
    pop   cx
    ret
;
;   dx is high,
;   bx is low.
;   al is data
;======================
upd_crc:
    push  cx
    mov   cx,8     ; do 8 bits;cx=次数
    mov   ah,0
upd_crc1:
    shl   bx,1     ; shift bx  ;bx在最开始时被设置为0xffff
                   ;逻辑左移1位,高位进c,地位补0
    rcl   dx,1     ; through dx;dx最开始被设置为0xffff
               ;带进位循环左移,高位进c,c进低位
    rcl   ah,1     ; carry is at bottom of ah
                ;带进位循环左移,高位进c,c进低位
    xor   ah,al    ; xor with lsb of data
              ;逻辑异或,结果放在左边的ah里,相同为0,不同为1
    rcr   ah,1     ; and put in carry bit
              ;带进位的循环右移,c进高位,低位进c
    jnc   upd_crc2
;
;   autodin is x^32+x^26+x^23x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1
;
    xor   dx,0000010011000001b
    xor   bx,0001110110110110b + 1   ;plus one for end-around carry.
upd_crc2:
    shr   al,1     ; shift the data
      ; 循环右移,高位补0,低位进c
    loop  upd_crc1
    pop   cx
    ret
以下是在keil c51里的c语言程序,为斑竹所写
点击这里打开
//作者laogu  http://www.laogu.com
//程序的功能是根据多播地址multicast_address[6]的值,计算出MAR0-MAR7,就是multicast_filter[8];
//本程序指计算一个多播地址。如果有多个多播地址,将每个多播地址生成的multicast_filter[8]相或就可以了,
//例如根据多播地址 01:00:5e:00:00:01生成的 value1=multicast_filter[8];
//根据多播地址     01:00:5e:00:00:02生成的 value2=multicast_filter[8];
//那么对这两个多播地址生成的multicast_filter[8]=value1  |  value2 ;将两个值相或
//很容易从这里得到如果要接收所有多播地址的数据包,MAR0--MAR7必须设置为0xff,就是说
//multicast_filter[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
#define al ax_value.bytes.low
#define bl bx_value.bytes.low
#define cl cx_value.bytes.low
#define ah ax_value.bytes.high
#define bh bx_value.bytes.high
#define dh dx_value.bytes.high
#define ax ax_value.word
#define bx bx_value.word
#define cx cx_value.word
#define dx dx_value.word
#define shl_bx if((bx&0x8000)!=0){cf=1;}else{cf=0;};bx=bx<<1;
#define shl_al if((al&0x80)!=0){cf=1;}else{cf=0;};al=al<<1;
#define shr_al if((al&0x01)!=0){cf=1;}else{cf=0;};al=al>>1;
#define rcl_dx if((dx&0x8000)!=0){cf_temp=1;}else{cf_temp=0;};dx=dx<<1;if(cf){dx=dx+1;};cf=cf_temp;
#define rcl_ah if((ah&0x80)!=0){cf_temp=1;}else{cf_temp=0;};ah=ah<<1;if(cf){ah=ah+1;};cf=cf_temp;
#define rcr_ah if((ah&0x01)!=0){cf_temp=1;}else{cf_temp=0;};ah=ah>>1;if(cf){ah=ah+0x80;};cf=cf_temp;
#define rol_al if((al&0x80)!=0){cf=1;}else{cf=0;};al=al<<1;if(cf){al=al+1;};
#define ror_al if((al&0x01)!=0){cf=1;}else{cf=0;};al=al>>1;if(cf){al=al+0x80;};
union u {unsigned int word;
         struct{unsigned char high;unsigned char low;}bytes;//字节顺序为高位在前的2byte结构
   };
union u ax_value;
union u bx_value;
union u cx_value;
union u dx_value;
bit cf;
bit cf_temp;
unsigned char multicast_address[6]={0x01,0x00,0x5e,0x00,0x00,0x00};
//unsigned char multicast_address[6]={0x00,0x00,0x00,0x5e,0x00,0x01};  //只计算一个多播地址
//unsigned char multicast_address[6]={0x01,0x80,0xc2,0x00,0x00,0x00};
unsigned char multicast_filter[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
                                      //结果放在这里,就是MAR0--MAR7的值
//;;0x41,0x00,0x00,0x80,0x00,0x00,0x00,0x00;
void up_crc(unsigned char al_byte)
{
al=al_byte;
ah=0;
for (cx=0;cx<8;cx++)
{
shl_bx;
rcl_dx;
rcl_ah;
ah=ah^al;
rcr_ah;
if(cf){
   dx=dx^0x04c1;//        0000,0100,1100,0001b
   bx=bx^0x1db7; //0001,1101,1011,0110b + 1 ;plus one for end-around carry.
      }
shr_al;

}

}
void add_mc_bits()
{
unsigned char i;
bx=0xffff;
dx=0xffff;
for(i=0;i<6;i++)
{
up_crc(multicast_address);
}
cl=8;
al=dh;
rol_al;
rol_al;
rol_al;
al=al&0x07;
bl=al;
bh=bh^bh;
al=dh;
ror_al;
ror_al;
al=al&0x07;
cl=al;
al=1;
for(i=0;i<cl;i++)
{
shl_al;
}
multicast_filter[bx]=multicast_filter[bx] | al;
}
main()
{
add_mc_bits(); //计算多播地址的MAR0-MAR7.
while(1);
}


使用特权

评论回复
板凳
6019赵文|  楼主 | 2011-6-16 15:04 | 只看该作者
以太网的地址为48位,由ieee统一分配给网卡制造商,每个网卡的地址都必须是全球唯一的。共6个字节的长度

字节543210
47。。4039。。3231。。2423。。1615。。87。。0
例子080009A04AB1
我们需要注意的是以太网地址的第32位是组播地址的标志位:

47。。333231。。2423。。0
制造厂商标识组播标志位制造厂商标识系列号

共6个字节,其中前面3个字节(除了第32位),组成制造厂商的标识,每个制造厂商的前3个字节是不同的,如果两个网卡的前面3个字节是一样的,那么这个卡是同一个公司制造的。同时通过该3个字节就可以反过来知道这个卡是哪个厂制造的。后面3个字节为系列号,由制造厂商给自己生产的网卡分配一个号码,不同网卡的号码必须不同, 网卡地址的制造厂商的3个字节的标识中,例如上面的08:00:09 ,080009 是惠普公司的标识,表示这个卡是惠普公司制造的。3个字节的第一个字节,必须为偶数,上面的08是一个偶数,是因为第32位,就是第一个字节的最低位是组播标识,必须为0。
以下
X0:XX:XX:XX:XX:XX
X2:XX:XX:XX:XX:XX
X4:XX:XX:XX:XX:XX

X6:XX:XX:XX:XX:XX
X8:XX:XX:XX:XX:XX
XA:XX:XX:XX:XX:XX
XC:XX:XX:XX:XX:XX

XE:XX:XX:XX:XX:XX

为合法的以太网网卡地址。上面的X代表0-F中的任一个。如果你不是购买网卡,而是自己购买芯片制造,那么地址怎么办?可以自己使用一个还没有被ieee分配的厂商编号就可以了。就算是使用已经分配的厂商编号也没有不可,只要你能保证在你使用的局域网内,任何两个网卡的地址不一样就可以了。

地址
FF:FF:FF:FF:FF:FF
为广播地址,只能用在目的地址段,不能作为源地址段。目的地址为广播地址的数据包,可以被一个局域网内的所有网卡接收到。

地址

X1:XX:XX:XX:XX:XX
X3:XX:XX:XX:XX:XX
X5:XX:XX:XX:XX:XX

X7:XX:XX:XX:XX:XX
X9:XX:XX:XX:XX:XX
XB:XX:XX:XX:XX:XX
XD:XX:XX:XX:XX:XX

XF:XX:XX:XX:XX:XX为组播地址,只能作为目的地址,不能作为源地址。组播地址可以被支持该组播地址的一组网卡接收到。组播地址主要用在视频广播,远程唤醒(通过发一个特殊的数据包使网卡产生一个中断信号,启动电脑),游戏(多个人在局域网里联机打游戏)里等。
以下是一些具体的组播地址:
地址 范围
01:00:5E:00:00:00---01:00:5E:7F:FF:FF 用于ip地址的组播
其他组播地址跟tcp/ip无关,不做介绍。

网卡可以接收以下3种地址的数据包:
第一种 目的地址跟自己的网卡地址是一样的数据包
第二种 目的地址为FF:FF:FF:FF:FF:FF广播地址的数据包
第三种 目的地址为跟自己的组播地址范围相同的数据包

那么在以太网的应用当中,如果你希望你的数据包只发给一个网卡,目的地址用对方的网卡地址
如果你想把数据包发给所有的网卡,目的地址用广播地址
如果你想把数据包发给一组网卡,目的地址用组播地址。

rtl8019跟网卡地址有关的寄存器:




物理地址寄存器,位于page1,共6个字节,这就是网卡的地址,复位之后该6个寄存器的值是不定的。
要由用户将网卡地址写入到该6个寄存器中,以后网卡接收到的数据包,会将数据包的目的地址跟这6个寄存器的值进行比较,结果相同的数据包被接收下来。上电复位时从93c46读入的网卡地址不会自动写入到这里,而是放在rtl8019as的内存地址0000H,0002H,0004H,0006H,0008H,000AH,0000CH里。你的程序要从这6个内存地址里读出网卡地址,写入到PAR0-5 共6个寄存器地址里。如果你的系统没有使用93c46来存储该网卡地址,那么要由你的软件自行产生或分配一个网卡地址,写入到6个寄存器里(比如你可以把网卡地址存储在单片机的flash rom里,存储在24c02的eeprom里等)。

跟组播地址有关的寄存器:


为8个寄存器,提供对组播地址的过滤。跟crc的逻辑有关。我对于该8个寄存器跟组播地址的关系不是很清楚,也没有找到相关的资料。将该8个寄存器全部写入0FFH,可以接收所有的组播地址地数据包。全部写入0,将不接收任何组播地址的数据包。在windows 98操作系统里,操作系统写入到这8个寄存器的值为:
MAR0 :00H
MAR1 :41H
MAR2 :00H
MAR3 :80H
MAR4 :00H
MAR5 :00H
MAR6 :00H
MAR7 :00H

写入的这8个值跟具体的组播地址是什么关系?我也不知道。lphard的方案是写入8个0xff 。
那么在嵌入式应用中应该如何处理?建议为全部写入0xff。如果不想支持组播,可以不用理这8个寄存器,或全部写入0。


跟网卡地址有关的标志位:


[size=+1]其中的第3位ATD,0为正常操作,1为由组播地址控制(用作流控)。我们把这个位设置为0。
我们不需要使用流控,因为流控的标准不被所有的网卡支持,有些网卡支持,有些不支持。


其中的PRO,AM,AB跟地址有关:
PRO为1时,将接收所有的数据包,不管任何地址, 统统收下来。通常用在一些网桥,或一些用来监视网络的电脑里。sniffer软件就是利用这个特性,将以太网上所有数据包都收下来进行分析,以统计以太网里的数据传输率,冲突,出错情况,网卡地址情况,ip数据包等情况。
PRO为0时,接收跟自己的地址一样的数据包,其他目的地址的被丢弃(不包括广播和组播包)。我们设置为0就可以了。
AM=1时,接收组播地址的数据包,AM=0时,不接收组播地址的数据包。 将该位根据你的情况设置为1或0,推荐设置为1。
AB=1时,接收广播地址的数据包,AB=0时,不接收广播地址FF:FF:FF:FF:FF:FF的数据包。该位要设置为1,才能实现tcp/ip协议。


PHY跟地址有关:
为接收的情况报告。

[size=+1]参考:IP组播地址转换为以太网组播地址
二、组播地址

    大家知道,IP地址空间被划分为A、B、C三类。第四类即D类地址被保留用做组播地址。在第四版的IP协议(IPv4)中,从224.0.0.0到239.255.255.255间的所有IP地址都属于D类地址。
    组播地址中最重要的是第24位到27位间的这四位,对应到十进制是224到239,其它28位保留用做组播的组标识,如下图所示:
         
                 图1 组播地址示意图

    IPv4的组播地址在网络层要转换成网络物理地址。对一个单播的网络地址,通过ARP协议可以获取与IP地址对应的物理地址。但在组播方式下ARP协议无法完成类似功能,必须得用其它的方法获取物理地址。在下面列出的RFC文档中提出了完成这个转换过程的方法:
    RFC1112:Multicast IPv4 to Ethernet physical address correspondence

    RFC1390:Correspondence to FDDI

    RFC1469:Correspondence to Token-Ring networks
    在最大的以太网地址范围内,转换过程是这样的:将以太网地址的前24位最固定为01:00:5E,这几位是重要的标志位。紧接着的一位固定为0,其它23位用IPv4组播地址中的低23位来填充。该转换过程如下图所示:

                 
                        图2 地址转换示意图

    例如,组播地址为224.0.0.5其以太网物理地址为01:00:5E:00:00:05。
还有一些特殊的IPv4组播地址:
    224.0.0.1:标识子网中的所有主机。同一个子网中具有组播功能的主机都是这个组的成员。
    224.0.0.2:该地址用来标识网络中每个具有组播功有的路由器。
    224.0.0.0----224.0.0.255范围内的地址被分配给了低层次的协议。向这些范围内的地址发送数据包,有组播功能的路由器将不会为其提供路由。
    239.0.0.0----239.255.255.255间的地址分配用做管理用途。这些地址被分配给局部的每一个组织,但不可以分配到组织外部,组织内的路由器不向在组织外的地址提供路由。
    除了上面列出的部分组播地址外,还有许多的组播地址。在最新版本的RFC文档“Assinged Numbers”中有完整的介绍。
    下面的表中列出了全部的组播地址空间,同时还列出了相应的地址段的常用名称及其TTL(IP包的存活时间)。在IPv4组播方式下,TTL有双重意义:正如大家所知的,TTL原本用来控制数据包在网络中的存活时间,防止由于路由器配置错误导致出现数据包传播的死循环;在组播方式下,它还代表了数据包的活动范围,如:数据包在网络中能够传送多远?这样就可以基于数据包的分类来定义其传送范围。
    范围 TTL 地址区间 描述
节点(Node) 0 只能向本机发送的数据包,不能
                                         向网络中的其它接口传送
链路(Link) 1 224.0.0.0-224.0.0.255 只能在发送主机所在的一个子网内的
                                        传送,不会通过路由器转发。
部门 32 239.255.0.0-239.255.255.255 只在整个组织下的一个部门内
(Department) 传送
组织 64 239.192.0.0--239.195.255.255 在整个组织内传送
(Organization)
全局(Global)255 224.0.1.0--238.255.255.255 没有限制,可全局范围内传送


三、组播的工作过程
  
    在局域网内,主机的网络接口将到目的主机的数据包发送到高层,这些数据包中的目的地址是物理接口地址或广播地址。
    如果主机已经加入到一个组播组中,主机的网络接口就会识别出发送到该组成员的数据包。
    因此,如果主机接口的物理地址为80:C0:F6:A0:4A:B1,其加入的组播组为224.0.1.10,则发送给主机的数据包中的目的地址必是下面三种类型之一:
    接口地址:80:C0:F6:A0:4A:B1
    广播地址:FF:FF:FF:FF:FF:FF
    组播地址:01:00:5E:00:01:0A
    广域网中,路由器必须支持组播路由。当主机中运行的进程加入到某个组播组中时,主机向子网中的所有组播路由器发送IGMP(Internet分组管理协议)报文,告诉路由器凡是发送到这个组播组的组播报文都必须发送到本地的子网中,这样主机的进程就可以接收到报文了。子网中的路由器再通知其它的路由器,这些路由器就知道该将组播报文转发到哪些子网中去。
    子网中的路由器也向224.0.0.1发送一个IGMP报文(224.0.0.1代表组中的全部主机),要求组中的主机提供组的相关信息。组中的主机收到这个报文后,都各将计数器的值设为随机值,当计数器递减为0时再向路由器发送应答。这样就防止了组中所有的主机同时向路由器发送应答,造成网络拥塞。主机向组播地址发送一个报文做为对路由器的应答,组中的其它主机一旦看到这个应答报文,就不再发送应答报文了,因为组中的主机向路由器提供的都是相同的信息,所以子网路由器只需得到组中一个主机提供的信息就可以了。
    如果组中的主机都退出了,路由器就收不到应答,因此路由器认为该组目前没有主机加入,遂停止到该子网报文的路由。IGMPv2的解决方案是:组中的主机在退出时向224.0.0.2 发送报文通知组播路由器。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

350

主题

1515

帖子

1

粉丝