JAVA实现UDP单播组播

组播

组播发送端

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

/**
 * @author yichuan@iscas.ac.cn
 * @version 1.0
 * @date 2021/10/20 14:44
 */
public class MulticastSender {
    public static void main(String[] args) throws IOException
    {
        int port = 8888;
        byte[] msg = "Connection successfully!!!".getBytes();

        InetAddress inetRemoteAddr = InetAddress.getByName("224.0.0.5");

        /*
         * Java UDP组播应用程序主要通过MulticastSocket实例进行通信,它是DatagramSocket的是一个子类,
         * 其中包含了一些额外的可以控制多播的属性.
         *
         * 注意:
         *
         * 多播数据报包实际上可以通过DatagramSocket发送,只需要简单地指定一个多播地址。
         * 我们这里使用MulticastSocket,是因为它具有DatagramSocket没有的能力
         */
        MulticastSocket client = new MulticastSocket();

        DatagramPacket sendPack = new DatagramPacket(msg, msg.length,
                inetRemoteAddr, port);

        client.send(sendPack);

        System.out.println("Client send msg complete");

        client.close();

    }
}
/**
 * 组播组可以是永久的也可以是临时的。组播组地址中,有一部分由官方分配的,称为永久组播组。永久组播组保持不变的是它的ip地址,组中的成员构成可以发生变化。永久组播组中成员的数量都可以是任意的,甚至可以为零。那些没有保留下来供永久组播组使用的ip组播地址,可以被临时组播组利用。
 * 224.0.0.0~224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;
 * 224.0.1.0~224.0.1.255是公用组播地址,可以用于Internet;
 * 224.0.2.0~238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效;
 * 239.0.0.0~239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效。
 *
 * 组播地址列表如下:
 * 224.0.0.0 基准地址(保留)
 * 224.0.0.1 所有主机的地址 (包括所有路由器地址)
 * 224.0.0.2 所有组播路由器的地址
 * 224.0.0.3 不分配
 * 224.0.0.4 dvmrp路由器
 * 224.0.0.5 所有ospf路由器
 * 224.0.0.6 ospf DR/BDR
 * 224.0.0.7 st路由器
 * 224.0.0.8 st主机
 * 224.0.0.9 rip-2路由器
 * 224.0.0.10 Eigrp路由器
 * 224.0.0.11 活动代理
 * 224.0.0.12 dhcp 服务器/中继代理
 * 224.0.0.13 所有pim路由器
 * 224.0.0.14 rsvp封装
 * 224.0.0.15 所有cbt路由器
 * 224.0.0.16 指定sbm
 * 224.0.0.17 所有sbms
 * 224.0.0.18 vrrp
 */

组播接收端


import old.util.NetworkUtil;
import java.net.*;
import java.util.Arrays;
import java.util.List;

/**
 * @author yichuan@iscas.ac.cn
 * @version 1.0
 * @date 2021/10/20 14:45
 */
public class MulticasReceiveNetworkCard {
    public static void main(String[] args) throws Exception
    {
        //InetAddress inetRemoteAddr = InetAddress.getByName("224.0.0.5");
        InetAddress group = InetAddress.getByName("224.0.0.5");
        DatagramPacket recvPack = new DatagramPacket(new byte[1024], 1024);


        //MulticastSocket server = new MulticastSocket(8888);
        int port = 8888;
        MulticastSocket socket = new MulticastSocket(port);

        int randomPort = port + 30000;
        List<NetworkInterface> addressList = NetworkUtil.getNetworkInterfaces();
        for (NetworkInterface networkInterface : addressList) {
            InetSocketAddress inetSocketAddress = new
                    InetSocketAddress(group, randomPort);
            //将有效网卡加入组播
            socket.joinGroup(inetSocketAddress, networkInterface);
            randomPort++;
        }
        /*
         * 如果是发送数据报包,可以不加入多播组; 如果是接收数据报包,必须加入多播组; 这里是接收数据报包,所以必须加入多播组;
         */
        //server.joinGroup(inetRemoteAddr);

        System.out.println("---------------------------------");
        System.out.println("SocketServer current start......");
        System.out.println("---------------------------------");

        while (true)
        {
            socket.receive(recvPack);
            //server.receive(recvPack);

            byte[] recvByte = Arrays.copyOfRange(recvPack.getData(), 0,
                    recvPack.getLength());

            System.out.println("SocketServer receive msg:" + new String(recvByte));
        }
    }
}

网卡工具类

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * @author yichuan@iscas.ac.cn
 * @version 1.0
 * @date 2021/10/25 10:48
 */
public class NetworkUtil {
    private final static String LOCAL_IP = "127.0.0.1";
    /**
     * 获取本机有效所有网卡地址
     *
     * @return  List<NetworkInterface> ip列表
     * @throws
     */
    public static List<NetworkInterface> getNetworkInterfaces() throws Exception {
        List<NetworkInterface> localIPlist = new ArrayList<NetworkInterface>();
        Enumeration<NetworkInterface> interfs =
                NetworkInterface.getNetworkInterfaces();
        if (interfs == null) {
            return null;
        }
        while (interfs.hasMoreElements()) {
            NetworkInterface interf = interfs.nextElement();
            Enumeration<InetAddress> addres = interf.getInetAddresses();
            while (addres.hasMoreElements()) {
                InetAddress in = addres.nextElement();
                if (in instanceof Inet4Address) {
                    if (!LOCAL_IP.equals(in.getHostAddress())){
                        localIPlist.add(interf);
                    }
                }
            }
        }
        return localIPlist;
    }
}

单播

单播发送端

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
 * @author yichuan@iscas.ac.cn
 * @version 1.0
 * @date 2021/10/20 9:12
 */
/*
 * 实现UDP协议的发送端:
 *     实现封装数据的类 java.net.DatagramPacket 将你的数据包装
 *     实现数据传输类    java.net.DatagramSocket 将数据包发出去
 *
 *    实现步骤:
 *        1.创建DatagramPacket对象,封装数据,接收的地址和端口
 *        2.创建DatagramSocket对象,
 *        3.调用DatagramSocket类的方法send,发送数据包
 *        4.关闭资源
 *
 *    DatagramPacket构造方法:
 *        DatagramPacket(byte[] buf,int length,InetAddress address,int port)
 *
 *    DatagramSocket构造方法:
 *        DatagramSocket()空参数
 *        方法:send(DatagramPacket d)
 *
 *
 */
public class UDPSend {
    public static void main(String[] args) throws IOException {
        //创建数据包对象,封装要发送的数据,接受端IP,端口
        byte[] data="你好UDP".getBytes();
        //创建InetAddress对象,封装自己的IP地址
        InetAddress inet=InetAddress.getByName("127.0.0.1");
        DatagramPacket dp=new DatagramPacket(data,data.length,inet,6000);
        //创建DatagramSocket对象,数据包的发送和接受对象
        DatagramSocket ds=new DatagramSocket();
        //调用ds对象的方法send,发送数据包
        ds.send(dp);
        ds.close();

    }
}

单播接收端

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
 * @author yichuan@iscas.ac.cn
 * @version 1.0
 * @date 2021/10/20 9:17
 */
/*
 *     实现UDP接收端
 *         实现封装数据包java.net.DatagramPacket 将数据接收
 *         实现输出传输    java.net.DatagramSocket 接受数据包
 *
 *     实现步骤:
 *         1.创建DatagramSocket对象,绑定端口号
 *               要和发送数据端口号一致
 *         2.创建字节数组,接受发来的数组
 *         3.创建数据包对象DatagramPacket
 *         4.调用DatagramSocket对象方法 receive(DatagramPacket dp)
 *               接受数据,数据放在数据包中
 *         5.拆包
 *                 发送的IP地址
 *                  数据包对象DatagramPacket()方法getAddress()获取的是发送端的IP地址对象
 *                 接受到的字节个数
 *                  数据包对象DatagramPacket()方法getLength()
 *                 发送方的端口号
 *              数据包对象DatagramPacket()方法getPort()
 *         6.关闭资源
 */
public class UDPReceive {
    public static void main(String[] args) throws IOException {
        //创建数据包传输对象DatagramSocket 绑定端口号
        DatagramSocket ds=new DatagramSocket(6000);
        //创建字节数组
        byte[] data=new byte[1024];
        //创建数据包对象,传递字节数组
        DatagramPacket dp=new DatagramPacket(data, data.length);
        //调用ds对象的方法receive传递数据包
        ds.receive(dp);

        //获取发送端的IP地址对象
        String ip=dp.getAddress().getHostAddress();

        //获取发送的端口号
        int port=dp.getPort();

        //获取接收到的字节数
        int length=dp.getLength();
        System.out.println(new String(data,0,length)+"...."+ip+":"+port);
        ds.close();
    }
}

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值