使用UDP实现广播发送

需求描述:

第一步:现在有ClientA向网络中的所有设备的8888端口发送广播,ClientB需要监听8888端口来收到广播信息
第二步:ClientB在收到广播信息后需要给予回执。需要将消息回复过去

参考代码

/**
 * 广播出去,并接受收到信息的回执
 */
public class ClientA {
    private static final Integer BroadCast_Port = 8888;//广播端口
    private static final Integer Receive_Port = 9999;//别人的回执端口
    private static final String SENDSTR = "明天都来家里吃饭啊!";
    public static void main(String[] args) throws Exception {
        System.out.println("准备好我要广播了-------");
        MyLisener lisener = lisener();
        sendBroadCast();
        List<InetAddress> inetAddresses = null;
        while(true){
            if(99 == System.in.read()){//如果按了c就退出
                inetAddresses = lisener.closeAndGetAddress();
                break;
            }
        }
        inetAddresses = lisener.closeAndGetAddress();
        System.out.println("收到参加聚会的人员信息----------------------");
        for (InetAddress inetAddress : inetAddresses) {
            System.out.println("人员信息->>>>>"+inetAddress.getHostAddress());
        }
        System.out.println("------------------------------------------");
        System.out.println("所有都结束了");
    }

    private static void sendBroadCast() throws IOException {
        //发送广播
        DatagramSocket datagramSocket = new DatagramSocket();
        DatagramPacket datagramPacket = new DatagramPacket(SENDSTR.getBytes("UTF-8"),SENDSTR.getBytes().length);
        datagramPacket.setPort(BroadCast_Port);
        datagramPacket.setAddress(InetAddress.getByName("255.255.255.255"));
        datagramSocket.send(datagramPacket);
    }

    private static MyLisener lisener() throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(1);
        MyLisener myLisener = new MyLisener(countDownLatch);
        myLisener.start();
        countDownLatch.await();
        return myLisener;

    }

    private static class MyLisener extends Thread{
        private DatagramSocket ds;
        private boolean finished = false;
        private final CountDownLatch countDownLatch;
        private final List<InetAddress> devices = new ArrayList<>();
        private MyLisener(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            try {
                ds = new DatagramSocket(Receive_Port);
                countDownLatch.countDown();
                while(!finished){
                    byte[] bytes = new byte[100];
                    DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
                    ds.receive(datagramPacket);
                    devices.add(datagramPacket.getAddress());
                    System.out.println("获得数据 ->>>> "+new String(datagramPacket.getData(),0,datagramPacket.getLength()));
                }
            }catch (Exception e){
//                e.printStackTrace();
            }

        }

        public List<InetAddress> closeAndGetAddress(){
            if(ds != null){
                ds.close();
                ds = null;
            }
            this.finished = true;
            //我不允许外面的更改
            return Collections.unmodifiableList(devices);
        }
    }
}
/**
 * 用来接收数据
 */
public class ClientB {
    private static final Integer Receive_Port = 8888;//广播端口
    private static final Integer Send_Port = 9999;//别人的回执端口
    private final static String SENDSTR = "好的,我要吃八碗<QAQ>";
    public static void main(String[] args) throws IOException {
        System.out.println("开始启动");
        MyCustomer myCustomer = new MyCustomer();
        myCustomer.start();
        while(true){
            if(99 == System.in.read()){//如果按了c就退出
                myCustomer.exit();
                break;
            }
        }
    }

    private static class MyCustomer extends Thread{
        private DatagramSocket ds = null;
        private boolean finished = false;
        @Override
        public void run() {
            try {
                ds = new DatagramSocket(Receive_Port);
                while(!finished){
                    byte[] bytes = new byte[100];
                    DatagramPacket receivePacket = new DatagramPacket(bytes, bytes.length);
                    ds.receive(receivePacket);
                    System.out.println(new String(receivePacket.getData(),0,receivePacket.getLength()));
                    //发送数据
                    System.out.println("发送回执");
                    DatagramPacket sendPacket = new DatagramPacket(SENDSTR.getBytes(), SENDSTR.getBytes().length);
                    //发送到广播的那个地址
                    sendPacket.setAddress(receivePacket.getAddress());
                    sendPacket.setPort(Send_Port);
                    ds.send(sendPacket);
                }
            }catch (Exception e){

            }
        }
        public void exit(){
            if(ds != null){
                ds.close();
                ds = null;
                finished = true;
            }
        }
    }
}

代码描述

ClientA代码描述:

此类中创建了一个lisener线程。因为需要开启一个端口来监听别人发来的消息,而且不想阻塞主线程,所以就新开了个线程。
在线程中使用到了countdownLatch,因为现在的设计思路是:先开启监听端口(接受消息的端口)再进行广播发送。也就是说在没有监听的时候让主线程阻塞,当监听了就不阻塞线程,就是使用CountDownLatch来实现的。

ClientB代码描述

此客户端为接受广播消息的一段,并给出回执
这边也创建一个线程。这里代码比较简单,暂无可说。。。

运行结果

clientA运行结果
在这里插入图片描述

clientB运行结果
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值