UDP单播、组播与广播详解及示例代码

前言:UDP是一种无连接的传输层协议,数据以报文形式传播,单次最大数据量为64KB(减去头部信息后实际更小)。UDP通信方式主要有三种:单播、组播和广播

本文将结合Java代码,详细介绍这三种UDP通信方式的实现方法。

1. UDP基础知识

  • 单播:一对一通信,发送端向指定IP和端口发送数据。

  • 组播:一对多通信,发送端向一个组播组地址发送数据,组内所有成员都能接收。

  • 广播:一对所有通信,发送端向局域网内所有主机广播数据。

UDP以报文形式传播信息,一次传播的信息最大为64KB,再减去头文件等信息,实际大小要小于64KB

UDP的传播方式主要分单播 组播 广播三种形式

单播为一对一的关系

组播为一对多的关系

广播为一对所有,对局域网内所有的电脑这个端口处均发送一次信息

2. 单播,如何实现?

分发送端与接收端。

发送端需要确定目标地址,目标端口,以及要传播的数据,如下 

package udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class SendMessage {
    public static void main(String[] args) throws Exception {
        //会绑定端口,去与外部的端口具体的链接
        //可以写也可以不写,随机端口
        DatagramSocket ds=new DatagramSocket();
        Scanner sc=new Scanner(System.in);
        //打包数据,这个数据的相关发送信息什么的
        String str;
        str=sc.next();
        while (!str.equals("886"))
        {
        byte[] bytes = str.getBytes();
        InetAddress byAddress = InetAddress.getByName("127.0.0.1");
        int port=10086;
        DatagramPacket dp=new DatagramPacket(bytes,bytes.length,byAddress,port);
        ds.send(dp);
        str=sc.next();
        }
        ds.close();
    }
}

发出去了,接收端怎么接受?端口要照,然后用数据包进行接收。只不过,如何打印出来数据呢?观察传播的数据类型就知道传播的是字节数组,把它进行字符串的转换即可

package udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ReceiveMessage {
    public static void main(String[] args) throws Exception{
        DatagramSocket ds=new DatagramSocket(10086);
        byte[] bytes=new byte[1024];
        DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
        while (true){
        ds.receive(dp);
        byte[] A= dp.getData();
        int len=dp.getLength();

        System.out.println("该数据从"+dp.getAddress()+"端口:"+dp.getPort());
            System.out.println("接受到数据:"+new String(A,0,len));
        }
        //ds.close();
    }

}

3. 组播,如何实现?

组播的地址范围为224.0.0.0-239.255.255.255

这里面不是使用DatagramSocker了用的是MulticastSocket,同时绑定IP是通过join的方式绑定

发送端代码如下

package udp_many;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.Scanner;

public class SendMessage {
    //组播地址:224.0.0.0 ~ 239.255.255.255
    public static void main(String[] args) throws Exception {
        //会绑定端口,去与外部的端口具体的链接
        //可以写也可以不写,随机端口
        MulticastSocket ds=new MulticastSocket();
        Scanner sc=new Scanner(System.in);
        //打包数据,这个数据的相关发送信息什么的
        String str;
        str=sc.next();
        byte[] bytes = str.getBytes();
        InetAddress byAddress = InetAddress.getByName("224.0.0.1");
        int port=10000;
        DatagramPacket dp=new DatagramPacket(bytes,bytes.length,byAddress,port);
        ds.send(dp);
        str=sc.next();

        ds.close();
    }
}

接收端代码如下

package udp_many;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class ReceiveMessage{
    public static void main(String[] args) throws Exception{
        //这里面接收端可以是多个,多个接收端接受多个发送端发送的信息
        MulticastSocket ds=new MulticastSocket(10000);

        InetAddress address=InetAddress.getByName("224.0.0.1");
        ds.joinGroup(address);

        byte[] bytes=new byte[1024];
        DatagramPacket dp=new DatagramPacket(bytes,bytes.length);

        ds.receive(dp);
        byte[] A= dp.getData();
        int len=dp.getLength();
        String name=dp.getAddress().getHostName();
        System.out.println("该数据从"+name+" "+dp.getAddress()+"端口:"+dp.getPort());
        System.out.println("接受到数据:"+new String(A,0,len));

        //ds.close();
    }

}

4. 广播如何实现?

广播与单播基本代码相似,只不过发送端绑定的目的IP不同

广播的IP主要为255.255.255.255,只不过,这个IP设置的前提为局域网下的所有电脑均处于同一网关下,下方这个图IPv4地址与网关地址不同,那么,电脑B与我们处于同一网关下,但是IPv4的网段不同即IPv4前三位不是10.9.23时,我们的255.255.255.255是不起作用的,这时候我们需要设置地址为10.9.63.255。

这样即使默认网关相同,但IPv4的网段不同,目的电脑也能收到

如果IPv4地址与默认网关的前三位相同,那么255.255.255.255起作用,同一局域网下的电脑可以接收到信息ok,代码如下

发送端

package udp_all;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class BroadcastSender {
    public static void main(String[] args) throws Exception {
        //           电脑1(发送端)    电脑2
        //IPv4地址   10.9.23.62       10.9.34.244
        //子网掩码    255.255.192.0    255.255.192.0
        //默认网关    10.9.63.254      10.9.63.254
        //发送端电脑一
        //发送端绑定10.9.23.255时,两台电脑均无法接收到代码
        //发送端绑定255.255.255.255时,电脑一可以收到信息,电脑二收不到信息
        //发送端绑定10.9.63.255时,两台电脑均可以收到信息,只不过电脑二接收两遍
        DatagramSocket socket = new DatagramSocket();
        socket.setBroadcast(true); // 允许广播

        Scanner scanner = new Scanner(System.in);
        System.out.println("输入消息,输入886退出:");

        while (true) {
            String message = scanner.nextLine();
            if ("886".equals(message)) break;

            byte[] data = message.getBytes();
            // 替换为你所在局域网的广播地址,例如192.168.1.255
            InetAddress broadcastAddress = InetAddress.getByName("10.9.63.255");
            int port = 8888;

            DatagramPacket packet = new DatagramPacket(data, data.length, broadcastAddress, port);
            socket.send(packet);
            System.out.println("广播消息已发送:" + message);
        }

        socket.close();
        scanner.close();
    }
}

  接收端

package udp_all;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Receive_all {
    public static void main(String[] args) throws Exception {
        
        int port = 8888;
        DatagramSocket socket = new DatagramSocket(port);
        System.out.println("Receiver started, waiting for broadcast messages...");

        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        while (true) {
            socket.receive(packet);
            String msg = new String(packet.getData(), 0, packet.getLength());
            System.out.println("Received: " + msg);
        }
    }
}

5. 总结与建议

  • UDP适合对实时性要求高但允许丢包的应用,如视频直播、在线游戏。

  • 代码示例均添加了异常处理,方便调试和运行。

如果你觉得本文对你有帮助,欢迎点赞、收藏和关注!
也欢迎留言交流UDP网络编程的更多问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值