UDP简单总结

UDP:用户数据报协议

  • 特点: 无连接、不可靠通信

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

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

  • Java代码常用方法
    • DatagramSocket():创建一个未绑定到任何本地地址和端口的DatagramSocket对象。
      DatagramSocket socket = new DatagramSocket();
      
    • DatagramSocket(int port):创建一个绑定到指定端口的DatagramSocket对象。
      DatagramSocket socket = new DatagramSocket(8080);
      
    • send(DatagramPacket packet):发送数据报包。
      byte[] data = "Hello, world!".getBytes();
      DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("localhost"), 8080);
      socket.send(packet);
      
    • receive(DatagramPacket packet):接收数据报包。
      byte[] buffer = new byte[1024];
      DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
      socket.receive(packet);
      
    • setSoTimeout(int timeout):设置接收超时时间(以毫秒为单位)。
      socket.setSoTimeout(5000); // 设置5秒超时
    • close():关闭套接字。
      socket.close();
      
    • bind(SocketAddress bindaddr):将套接字绑定到特定的本地地址和端口。
      socket.bind(new InetSocketAddress("localhost", 8080));
    • getLocalSocketAddress():获取套接字绑定的本地地址和端口。
      SocketAddress localAddress = socket.getLocalSocketAddress();
      

 下面是一个简单的示例代码,演示如何使用DatagramSocket发送和接收UDP数据报:

import java.net.*;

public class UDPSocketExample {
    public static void main(String[] args) {
        try {
            // 创建一个DatagramSocket对象并绑定到本地端口8080
            DatagramSocket socket = new DatagramSocket(8080);

            // 准备发送的消息字符串
            String message = "Hello, UDP!";
            
            // 将消息字符串转换为字节数组
            byte[] sendData = message.getBytes();
            
            // 获取接收者的地址(本地主机)和端口号(8081)
            InetAddress receiverAddress = InetAddress.getByName("localhost");
            int receiverPort = 8081;

            // 创建一个DatagramPacket对象,用于发送数据
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, receiverAddress, receiverPort);
            
            // 发送数据报包
            socket.send(sendPacket);
            System.out.println("Sent message: " + message);

            // 创建一个字节数组用于接收数据
            byte[] receiveData = new byte[1024];
            
            // 创建一个DatagramPacket对象,用于接收数据
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
            
            // 接收数据报包
            socket.receive(receivePacket);
            
            // 从接收的数据报包中获取消息字符串
            String receivedMessage = new String(receivePacket.getData(), 0, receivePacket.getLength());
            System.out.println("Received message: " + receivedMessage);

            // 关闭套接字
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

        在此示例中,我们使用DatagramSocket实现了一个简单的UDP通信程序。首先,我们创建了一个DatagramSocket对象并绑定到本地端口8080。然后,我们准备了要发送的消息字符串,并将其转换为字节数组。接着,我们获取了接收者的地址(本地主机)和端口号(8081),并创建了一个DatagramPacket对象用于发送数据。我们发送了数据报包,并在控制台打印了发送的消息。接着,我们创建了一个用于接收数据的字节数组和DatagramPacket对象,并接收了从本地端口8081发送的数据报包。最后,我们从接收的数据报包中获取消息字符串,并在控制台打印接收到的消息。最后,我们关闭了套接字。

        当然这只是实现了单发单收,我们可以利用死循环实现一个客户端和一个服务端的多发多收。下面我们利用线程实现多发多收。

下面是一个示例代码,演示如何实现多发多收的UDP通信:

import java.net.*;

public class MultiSendReceiveUDP {
    public static void main(String[] args) {
        try {
            // 创建DatagramSocket对象并绑定到本地端口8080
            DatagramSocket socket = new DatagramSocket(8080);

            // 启动接收线程
            Thread receiverThread = new Thread(new Receiver(socket));
            receiverThread.start();

            // 创建发送者线程并启动
            Thread sender1 = new Thread(new Sender(socket, "Message 1", "localhost", 8081));
            Thread sender2 = new Thread(new Sender(socket, "Message 2", "localhost", 8081));
            sender1.start();
            sender2.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 接收者线程类
    static class Receiver implements Runnable {
        private DatagramSocket socket;

        public Receiver(DatagramSocket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                // 创建一个字节数组用于接收数据
                byte[] receiveData = new byte[1024];

                while (true) {
                    // 创建一个DatagramPacket对象,用于接收数据
                    DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                    
                    // 接收数据报包
                    socket.receive(receivePacket);

                    // 从接收的数据报包中获取消息字符串
                    String receivedMessage = new String(receivePacket.getData(), 0, receivePacket.getLength());
                    System.out.println("Received message: " + receivedMessage);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 发送者线程类
    static class Sender implements Runnable {
        private DatagramSocket socket;
        private String message;
        private String receiverHost;
        private int receiverPort;

        public Sender(DatagramSocket socket, String message, String receiverHost, int receiverPort) {
            this.socket = socket;
            this.message = message;
            this.receiverHost = receiverHost;
            this.receiverPort = receiverPort;
        }

        @Override
        public void run() {
            try {
                // 将消息字符串转换为字节数组
                byte[] sendData = message.getBytes();
                
                // 获取接收者的地址和端口号
                InetAddress receiverAddress = InetAddress.getByName(receiverHost);

                // 创建一个DatagramPacket对象,用于发送数据
                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, receiverAddress, receiverPort);
                
                // 发送数据报包
                socket.send(sendPacket);
                System.out.println("Sent message: " + message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

        在此示例中,我们创建了一个MultiSendReceiveUDP类,其中包含了main方法,以及ReceiverSender类,分别用于接收和发送数据。在main方法中,我们创建了一个DatagramSocket对象并绑定到本地端口8080,并启动了一个接收者线程。然后,我们创建了两个发送者线程,并将它们分别启动。每个发送者线程将向本地主机的端口8081发送一条消息。接收者线程将一直接收来自发送者的消息,并在控制台打印出来。

相关推荐

  1. 简单Udp服务器

    2024-04-10 07:52:05       48 阅读
  2. udp简介4.0

    2024-04-10 07:52:05       59 阅读
  3. FFmpeg简单总结

    2024-04-10 07:52:05       49 阅读
  4. Redis简单总结

    2024-04-10 07:52:05       52 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-10 07:52:05       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-10 07:52:05       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-10 07:52:05       87 阅读
  4. Python语言-面向对象

    2024-04-10 07:52:05       96 阅读

热门阅读

  1. pnputil卸载Sangfor

    2024-04-10 07:52:05       39 阅读
  2. WPF —— 动画旋转变换

    2024-04-10 07:52:05       33 阅读
  3. 学习基于pytorch的VGG图像分类 day2

    2024-04-10 07:52:05       36 阅读
  4. 技术即服务:产品预告-1

    2024-04-10 07:52:05       34 阅读
  5. Redis+lua脚本限制ip多次输入错误密码

    2024-04-10 07:52:05       38 阅读
  6. 【AIGC调研系列】号称搜索引擎革命的Perplexity AI

    2024-04-10 07:52:05       40 阅读
  7. Ribbon负载均衡

    2024-04-10 07:52:05       34 阅读
  8. vue 组件间传值

    2024-04-10 07:52:05       28 阅读