zoukankan      html  css  js  c++  java
  • 多播(组播)与广播的技术实现

    1、组播是基于路由器之上实现的,要想网络内支持组播,需要有能够管理组播组的路由器或是三层交换机(带部分路由功能的交换机)。通常在我们的网络中,都会支持组播,即我们的程序可以使用组播技术,视频会议就使用这个技术。

    2、IP网络的多播一般通过多播IP地址来实现。多播IP地址就是D类IP地址,即224.0.0.0至239.255.255.255之间的IP地址。通常选择230之后的地址,使用UDP协议,把每个客户端(收端和发端)的socket都加入到这个地址上,之后客户端往这个地址上发送一个消息后,在这个组里的其他客户端都可以监听收到这个消息。

    3、在java中,java.net.MulticastSocket具有组播的功能,它是DatagramSocket的子类。具体程序如下:

    
    

    package com.udpdemo.multicast;

    import java.io.IOException;

    import java.net.DatagramPacket;

    import java.net.InetAddress;

    import java.net.MulticastSocket;

    import java.text.SimpleDateFormat;

    import java.util.Date;


    public
    class ServerMulticastSocketTest { public static void main(String[] args) { // TODO Auto-generated method stub MulticastSocket multicastSocket; try { multicastSocket = new MulticastSocket(); InetAddress address = InetAddress.getByName("239.0.0.1"); // 必须使用D类地址 multicastSocket.joinGroup(address); // 以D类地址为标识,加入同一个组才能实现广播 while (true) { String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); byte[] buf = time.getBytes(); DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length); datagramPacket.setAddress(address); // 接收地址和group的标识相同 datagramPacket.setPort(10000); // 发送至的端口号 multicastSocket.send(datagramPacket); Thread.sleep(1000); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
    package com.udpdemo.multicast;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.InetAddress;
    import java.net.MulticastSocket;
    
    public class ClientMulticastSocketTest {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            MulticastSocket multicastSocket;
            try {
                multicastSocket = new MulticastSocket(10000);
                 InetAddress address = InetAddress.getByName("239.0.0.1");
                    multicastSocket.joinGroup(address);
                    byte[] buf = new byte[1024];
                    
                    while (true) {
                        DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);
                        multicastSocket.receive(datagramPacket); // 接收数据,同样会进入阻塞状态
                        
                        byte[] message = new byte[datagramPacket.getLength()]; // 从buffer中截取收到的数据
                        System.arraycopy(buf, 0, message, 0, datagramPacket.getLength());
                        System.out.println(datagramPacket.getAddress());
                        System.out.println(new String(message));
                    }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } // 接收数据时需要指定监听的端口号
           
        }
    
    }

      关于MulticastSocket中的setTimeToLive方法:

        setTimeToLive public void setTimeToLive(int ttl)    throws IOException 该方法用于设置在此 MulticastSocket 上发出的多播数据包的默认生存时间,以便控制多播的范围。 ttl 必须在 0 <= ttl <= 255 范围内,否则将抛出 IllegalArgumentException。
      有时在多播环境下,如果使用使用MulticastSocket不能接收到多播的数据,可以考虑setTimeToLive方法,来配置数据包的生存时间,以便控制范围。(项目现场测试启示)


    4、广播功能:

        使用255.255.255.255(或者是192.168.10.255,具体ip地址上设置第四个参数为255是本网段的广播地址)的IP地址,所有的客户端都监听这个地址,发这个地址上发送消息,其他的客户端都会接收到。

      java中使用java.net.DatagramSocket来完成监听和发送,发送信息前,要开启广播,即调用socket的setbroadcast(true)。

     

    发送端Socket:
    void
    init_uSock(String sendText) throws Exception{ uSock = new DatagramSocket(); InetAddress host = InetAddress.getByName("192.168.10.255"); byte[] data = sendText.getBytes(); DatagramPacket packet = new DatagramPacket(data, data.length, host, office.local_udp_port); uSock.setBroadcast(true); uSock.send(packet); Log.e("UDP", "发送"); }
    接收端Socket:
    InetAddress addr
    = InetAddress.getByName("192.168.10.255"); DatagramSocket uServ = new DatagramSocket(office.local_udp_port,addr); while (uWork) { DatagramPacket packet = new DatagramPacket(new byte[102400], 102400); uServ.receive(packet); ............. }

      

  • 相关阅读:
    ThreadLocal应用场景以及源码分析
    ThreadLocal使用,应用场景,源码实现,内存泄漏
    ThreadLocal
    JBOSS默认连接池配置
    项目经验——jboss 配置数据库连接池
    InitialContext与lookup
    从零开发分布式数据库中间件 二、构建MyBatis的读写分离数据库中间件
    从零开发分布式数据库中间件 一、读写分离的数据库中间件
    appium+python自动化42-微信公众号
    appium+python自动化41-切换webview时候报chromedriver版本问题
  • 原文地址:https://www.cnblogs.com/wangle1001986/p/4692524.html
Copyright © 2011-2022 走看看