入门

特点:无连接、不可靠 。

不事先建立连接,数据按照包发,一包数据包括:自己的IP、程序端口,目的地IP、程序端口和数据(限制在64K内)等。

发送方不管对方是否在线,数据在中间丢失也不管,如果接收方收到数据也不会确认,故是不可靠的。

Java提供了一个java.net.DatagramSocket类来实现UDP通信。

UDP通信_客户端

 客户端

public class Client {
    public static void main(String[] args) throws Exception {
        // 1. 创建客户端对象(发报出去的人)
        DatagramSocket socket = new DatagramSocket();

        // 2. 创建数据包对象把要发送出去的数据打包(创建一个信差搬运子)
        /* public DatagramPacket(byte buf[], int length, InetAddress address, int port)
           参数一:封装要发送的数据。
           参数二:发送出去的数据大小(字节数组)。
           参数三:服务器的IP地址(找到服务器主机)
           参数四:服务器的端口号
        */
        byte[] bytes = "我是快乐的客户端,我爱编abc".getBytes();
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length,
                                                   InetAddress.getLocalHost(), 6666);

        // 3. 开始正式发送这个数据包给服务器出去
        socket.send(packet);

        System.out.println("客户端数据发送完毕~~");
        socket.close(); // 释放资源
    }
}

服务端

public class Server {
    public static void main(String[] args) throws Exception {
        // 1. 创建一个服务器端对象(创建一个接连接来的入口)
        DatagramSocket socket = new DatagramSocket(6666);

        // 2. 创建一个数据包对象,用于接收数据
        byte[] buffer = new byte[1024 * 64]; // 64KB
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        // 3. 开始正式使用数据包对象接收客户端发来的数据
        socket.receive(packet);

        // 4. 从字节数组中,把收到的数据提取出来打印出来
        // 获取本次数据提取了多少数据长度
        int len = packet.getLength();

        String rs = new String(buffer, 0, len);
        System.out.println(rs);
        System.out.println(packet.getAddress().getHostAddress() + " " + packet.getPort());// 获取客户端的IP地址和端口号
        socket.close();
    }
}

启动应该先启动服务端,服务端启动成功后会等待接收数据,再启动客户端。

多发多收

客户端

public class Client {
    public static void main(String[] args) throws Exception {
        // 1. 创建客户端对象(发报出去的人)
        DatagramSocket socket = new DatagramSocket();

        // 2. 创建数据包对象把要发送出去的数据打包(创建一个信差搬运子)
        /* public DatagramPacket(byte buf[], int length, InetAddress address, int port)
           参数一:封装要发送的数据。
           参数二:发送出去的数据大小(字节数组)。
           参数三:服务器的IP地址(找到服务器主机)
           参数四:服务器的端口号
        */
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请说:");
            String msg = sc.nextLine();
        
            // 一旦发现用户输入的exit命令,就退出循环
            if ("exit".equals(msg)) {
                System.out.println("欢迎下次光临!");
                socket.close(); // 释放资源
                break; // 跳出死循环
            }
        }

        DatagramPacket packet = new DatagramPacket(bytes, bytes.length,
                InetAddress.getLocalHost(), 6666);

        // 3. 开始正式发送这个数据包给服务器出去
        socket.send(packet);

        System.out.println("客户端数据发送完毕~~");
        socket.close(); // 释放资源
    }
}

服务端

public class Server {
    public static void main(String[] args) throws Exception {
        // 1. 创建一个服务器端对象(创建一个接连接来的入口)
        DatagramSocket socket = new DatagramSocket(6666);

        // 2. 创建一个数据包对象,用于接收数据
        byte[] buffer = new byte[1024 * 64]; // 64KB
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        // 3. 开始正式使用数据包对象接收客户端发来的数据
        while (true) {
            socket.receive(packet);

            // 4. 从字节数组中,把收到的数据提取出来打印出来
            // 获取本次数据提取了多少数据长度
            int len = packet.getLength();

            String rs = new String(buffer, 0, len);
            System.out.println(rs);
        }
    }
}

可以打开多个客户端,可以进行多对一收消息,前提把IDEA的多开打开,然后端口号设为默认。