UDP 广播与多播的实现

今天我这篇文章是基于这两篇文章修改了下:

http://blog.csdn.net/chenpeng19910926/article/details/51782821

http://blog.csdn.net/chenhanzhun/article/details/42006385

 

概述

 

主机可采用的通信方式有如下三种:

  1. 单播:单台主机与单台主机之间的数据通信;
  2. 广播:单台主机向网络中所有主机发送数据报的过程;
  3. 多播:单台主机向选定的一组主机发送数据报的过程;

 

        在网络协议中 IP 地址有三种方式,即为单播地址、广播地址 以及 多播地址。假设多个主机上的共享信道网络是以太网,每个以太网帧包含源主机和目的主机的以太网地址。若目的地址仅指定单个接收接口,则称为单播,在单播方式下,任意两台主机之间的通信不会干扰网内其他主机。若目的地址包含网上的所有主机的接收接口时,即一个主机要向网上所有主机发送帧,则称为广播。若一个主机把帧发送给属于多播组的多个主机,则称为多播。广播和多播仅应用于 UDP,可以将数据报文同时传给多个接收者,而 TCP 是一个面向连接的字节流协议,意味着只能运行于两个主机(由 IP 地址确定)内的两个进程(由端口号确定)之间的一条连接。

        首先了解下信道传送的帧在主机的过滤过程,如下图所示:

 

信道传送的帧在主机的过滤过程:

 

  1. 首先,网卡查看由信道传送给来的帧,确定是否接收该帧,对该帧进行检验和,若检验和出错,则将其丢弃,若检验和正确,则将其传送给设备驱动程序;
  2. 设备驱动程序也对来自接口卡的帧进行过滤,首先确认该帧指定的协议类型,然后进行多播过滤检测该主机是否属于多播地址说明的多播组,若帧的指定协议类型为 IP 协议,则将其传给 IP 层;
  3. 在 IP 层中根据 IP 地址中的源地址和目的地址进程过滤检测,若正常则将其传送给下一层,假设是 UDP 层;
  4. 每次 UDP 接收来自 IP 传送来的数据报,再根据端口号进行数据报过滤,若当前没有使用该端口号的进程,则将其丢弃,并产生一个 ICMP 不可达报文,若是检验和错误,则直接将其丢弃;

广播

广播可分为两大类:定向的广播 和 受限的广播

 

  1. 受限的广播:受限的广播地址是 255.255.255.255。该地址用于主机配置过程中 IP 数据报的目的地址,此时,主机并不知道它所在的网络掩码,甚至它的 IP 地址都不知道。任何情况下,路由器都不能转发目的地址为受限的广播地址的数据报,因此,受限的广播地址的数据报只能出现在本地网络中。
  2. 定向的广播:定向广播是将数据包发送到向本网络之外的特定网络所有主机,定向广播的目的地址是定向网络的广播地址;
    • 指向网络的广播:指向网络的广播地址是主机号全为 1 的地址,例如 A 类网络广播地址是netid.255.255.255,其中 netid 是 A 类网络的网络号。路由器必须转发指向网络的广播。
    • 指向子网的广播:指向子网的广播地址为主机号全为 1 且有特定子网号的地址。作为子网直接广播地址的 IP 地址需要了解子网掩码。
    • 指向所有子网的广播:指向所有子网的广播也需要连接目的网络的子网掩码,以便与指向网络的广播区分开来。指向所有子网的广播地址的子网号即主机全是 1。

 

多播

        多播也称为组播,组播是向指定的一组主机发送数据包。与单播相比,提高了发送数据包的效率,与广播相比,减少了网络流量。与广播不同的是,要实现组播需要在接受组播的客户机上安装相应的客户端程序。能接收发送一个特定多播组地址数据的主机集合称为主机组。

IP 多播提供两类服务:

 

  1. 向多个目的地址传送数据;
  2. 客户对服务器的请求;

 

总结

 

        单播是将数据报发给特定的单台主机,广播是将数据报发送给网络中所有的主机,而多播是将数据报发送给网络的一个主机组。广播的缺点是网络中的所有主机都必须处理数据报,而多播不需要,减少了网络流量。

 

 

我上篇文章UDP的数据传输实际上是广播的传输形式,现在详细讲多播。

广播发送数据流程:

 

同一网段所有主机都能接收,前提是端口要监听

客户端发送广播,开启端口监听的服务端接收并打印消息

多播发送数据流程:

 

多播数据报套接字类用于发送和接收 IP 多播包。MulticastSocket 是一种 (UDP) DatagramSocket,它具有加入 Internet 上其他多播主机的“组”的附加功能。

多播组通过 D 类 IP 地址和标准 UDP 端口号指定。D 类 IP 地址在 224.0.0.0 和 239.255.255.255 的范围内(包括两者)。地址 224.0.0.0 被保留,不应使用。

可以通过首先使用所需端口创建 MulticastSocket,然后调用 joinGroup(InetAddress groupAddr) 方法来加入多播组:(以上是jdk-doc的说明,补充如下:服务器和客户端必须都要加入相同的组播地址才可以

服务器端程序:

//接受组播和发送组播的数据报服务都要把组播地址添加进来  
        String host = "225.0.0.1";//多播地址  
        int port = 9998;  
        int length = 1024;  
        byte[] buf = new byte[length];  
        MulticastSocket ms = null;  
        DatagramPacket dp = null;  
        StringBuffer sbuf = new StringBuffer();  
        try {             
            ms = new MulticastSocket(port);  
            dp = new DatagramPacket(buf, length);  
              
            //加入多播地址  
            InetAddress group = InetAddress.getByName(host);  
            ms.joinGroup(group);  
              
            System.out.println("监听多播端口打开:");  
            ms.receive(dp);  
            ms.close();  
            int i;  
            for(i=0;i<1024;i++){  
                if(buf[i] == 0){  
                    break;  
                }  
                sbuf.append((char) buf[i]);  
            }             
            System.out.println("收到多播消息:" + sbuf.toString());            
        } catch (IOException e) {  
            e.printStackTrace();  
        }    

客户端程序

 

String host = "225.0.0.1";//多播地址  
        int port = 9998;  
        String message = "test-multicastSocket";  
        try {  
            InetAddress group = InetAddress.getByName(host);  
            MulticastSocket s = new MulticastSocket();  
            //加入多播组  
            s.joinGroup(group);  
            DatagramPacket dp = new DatagramPacket(message.getBytes(),message.length(),group,port);  
            s.send(dp);  
            s.close();  
        } catch (UnknownHostException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  

 

 

 

 

 

展开阅读全文

没有更多推荐了,返回首页