Java网络编程之UDP编程

本文详细介绍UDP通信原理,包括发送端和接收端的编程方法。通过实例演示如何在Java中实现教师与学生间的一对一网络聊天,涉及DatagramSocket、DatagramPacket的使用及多线程技术。

UDP通信编程方法详解

发送端

发送端需要做到以下几件事:

1、使用DatagramSocket指定端口,创建发送端

2、准备数据,转成字节数组

3、封装成DatagramPacket包裹,需要指定目的地

4、发送包裹

5、释放资源

简要的示例如下:

public class UdpClient {
    public static void main(String[] args) throws IOException {
        System.out.println("发送方启动中.......");
        // 1、使用DatagramSocket指定端口,创建发送端
        DatagramSocket client = new DatagramSocket(8888);
        // 2、准备数据 一定转成字节数组
        String data = "JOJO is YaoMing";
        byte[] datas = data.getBytes();
        //3、封装成DatagramPacket包裹,需要指定目的地
        DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
                new InetSocketAddress("localhost", 9999));
        // 4、发送包裹 send(DatagramPacket p)
        client.send(packet);
        // 5、释放资源
        client.close();
    }
}

接收端

接收端需要做到以下几件事:

1、使用DatagramSocket指定端口,创建接收端

2、准备容器,封装成DatagramPacket包裹

3、阻塞式接收包裹

4、分析数据

5、释放资源

示例如下:

public class UdpServer {
    public static void main(String[] args) throws Exception {
        System.out.println("接收方启动中");
        // 1、使用DatagramSocket指定端口,创建接收端
        DatagramSocket server = new DatagramSocket(9999);
        // 2、准备容器 封装成DatagramPacket包裹
        byte[] container = new byte[1024 * 60];
        DatagramPacket packet = new DatagramPacket(container, 0, container.length);
        // 3、阻塞式接收包裹 receive(DatagramPacket p)
        server.receive(packet);
        // 4、分析数据
        byte[] datas = packet.getData();
        int len = packet.getLength();
        System.out.println(new String(datas, 0, len));
        // 5、释放资源
        server.close();
    }
}

实现教师和学生一对一网络聊天

这里我们要基于控制台实现一个网络通讯,具体用到的知识包括上面讲的UDP通信,还包含了多线程的基础知识。

我们首先封装了发送信息的代码,和接收信息的代码。

TalkSend.java

/**
 * 发送端:使用面向对象封装
 * 多线程 发送消息
 *
 * @Author Nino 2019/10/22
 */
public class TalkSend implements Runnable {

    /**
     * 指定端口 创建发送端
     */
    private DatagramSocket client;

    /**
     * 准备发送的数据
     */
    private BufferedReader br;

    /**
     * 对方的IP地址
     */
    private String toIP;

    /**
     * 对方的端口
     */
    private int toPort;

    public TalkSend(int port, String toIP, int toPort) {
        this.toIP = toIP;
        this.toPort = toPort;
        try {
            client = new DatagramSocket(port);
            br = new BufferedReader(new InputStreamReader(System.in));
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void run() {
        while (true) {
            String data;
            try {
                data = br.readLine();

                byte[] datas = data.getBytes();
                // 封装成包
                DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
                        new InetSocketAddress(toIP, toPort));

                client.send(packet);

                // 中断循环条件
                if (data.equals("bye")) {
                    break;
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 释放资源
        client.close();
    }
}

TalkReceive.java

/**
 * 接收端:使用面向对象封装
 * 多线程 接收消息
 *
 * @Author Nino 2019/10/22
 */
public class TalkReceive implements Runnable {

    /**
     * 接收端
     */
    private DatagramSocket server;

    /**
     * 从哪来
     */
    private String from;

    public TalkReceive(int port, String from) {
        this.from = from;

        try {
            server = new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {

        while (true) {
            // 创建容器 并打包
            byte[] container = new byte[1024 * 64];
            DatagramPacket packet = new DatagramPacket(container, 0, container.length);

            try {
                // 阻塞式接收
                server.receive(packet);
                //分析数据
                byte[] datas = packet.getData();
                String data = new String(datas, 0, datas.length);
                System.out.println(from + ":" + data);

                if (data.equals("bye")) {
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        server.close();
    }
}

封装完毕后,只需要建学生和老师,然后分别创建发送和接收两个线程,即可实现通信。

注意端口不能被重复占用,同时校对好对方的IP地址,本机只需要输入localhost

TalkStudent.java

public class TalkStudent {
    public static void main(String[] args) {
        // 接收
        new Thread(new TalkReceive(9999, "teacher")).start();

        // 发送
        new Thread(new TalkSend(6666, "localhost", 7777)).start();
    }
}

TalkTeacher.java

public class TalkTeacher {
    public static void main(String[] args) {
        // 发送
        new Thread(new TalkSend(8888, "localhost", 9999)).start();

        // 接收
        new Thread(new TalkReceive(7777, "student")).start();

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值