• 【网络编程】UDP Socket编程


    数据报套接字: 使用传输层 UDP 协议

    UDP: 即 User Datagram Protocol(用户数据报协议),传输层协议

    UDP的特点:

    1. 无连接
    2. 不可靠传输
    3. 面向数据报
    4. 全双工
    5. 有接收缓冲区,无发送缓冲区
    6. 大小受限:一次最多传输64k

    对于数据报来说,可简单理解为,传输的数据是一块一块的,发送一块数据假如100个字节,必须一次发送,接收也必须一次接收100个字节,而不能分100次,每次接收1个字节。

    一. DatagramSocket

    DatagramSocket 是UDP Socket,用于发送和接收UDP数据报。

    构造方法:

    在这里插入图片描述

    方法:

    在这里插入图片描述

    二. DatagramPacket

    DatagramPacket是UDP Socket发送和接收的数据报。

    构造方法:

    在这里插入图片描述

    方法:

    在这里插入图片描述

    构造UDP发送的数据报时,需要传入 SocketAddress ,该对象可以使用 InetSocketAddress 来创建。

    三. InetSocketAddress

    InetSocketAddress 是SocketAddress 的子类

    构造方法:

    在这里插入图片描述

    四. 执行流程

    对于UDP协议来说,具有无连接,面向数据报的特征,即每次都是没有建立连接,并且一次发送全部数据报,一次接收全部的数据报。对于一个服务端来说,重要的是提供多个客户端的请求处理及响应,流程如下:

    在这里插入图片描述

    五. 代码示例: UDP 回显服务器

    服务器端代码:

    class UdpEchoServer {
        public DatagramSocket socket;
    
        //udp的服务器需要自己指定端口号
        public UdpEchoServer(int port) throws SocketException {
            socket=new DatagramSocket(port);
        }
    
        public void start() throws IOException {
            System.out.println("启动服务器");
            while(true){
                //三个步骤
                //1.接受客户端发来的请求
                //先构造出数据报(盘子)
                DatagramPacket requestPacket=new DatagramPacket(new byte[1024],1024);
                //接收数据
                socket.receive(requestPacket);//输出型参数, receive 会将数据填充到 requestPacket 中
                //将数据报解析成一个字符串
                String request=new String(requestPacket.getData(),0,
                        requestPacket.getLength(),"UTF-8");//注意这里求的长度直接用的是数据报
                //2.根据请求计算出响应
                String response=process(request);
                DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),
                        response.getBytes().length,//注意长度是字节数组的长度
                        requestPacket.getSocketAddress());//注意要加上IP地址和端口,这里合起来写了
                //3.响应返回给客户端
                socket.send(responsePacket);
                System.out.printf("[reqIP:%s  req端口号:%d][req:%s  resp:%s]\n",requestPacket.getAddress().toString(),
                        responsePacket.getPort(),request,response);
            }
        }
    
        /**
         *  根据请求计算响应, 这里面只是模拟, 直接返回了原字符串
         */
        public String process(String request){
            return request;
        }
    
        public static void main(String[] args) throws SocketException {
            UdpEchoServer udpEchoServer=new UdpEchoServer(9090);
            try {
                udpEchoServer.start();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    客户端代码:

    class UdpEchoClient {
        public DatagramSocket socket;
        //服务器的IP地址和端口号,传送数据时需要知道,放在数据报中
        public String serverIp;
        public int ServerPort;
        public UdpEchoClient(String serverIp,int serverPort) throws SocketException {
            socket=new DatagramSocket();//客户端利用系统随机分配的端口号,防止自己手动的端口号不能用
            this.serverIp=serverIp;
            this.ServerPort=serverPort;
        }
    
        public void start() throws IOException {
            Scanner scanner=new Scanner(System.in);
            while(true){
                //五个步骤
                //1.先接收用户输入的字符串
                System.out.println("->");
                String request=scanner.next();
                //2.构造数据报
                //注意数据报中除了数据内容还要包含服务器IP和端口
                DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),
                        request.getBytes().length, InetAddress.getByName(serverIp),ServerPort);
                //3.客户端发送数据报给服务器
                socket.send(requestPacket);
                //4.从服务器接收响应,并解析
                DatagramPacket responsePacket=new DatagramPacket(new byte[1024],1024);
                socket.receive(responsePacket);
                //解析数据
                String response=new String(responsePacket.getData(),0,
                        responsePacket.getLength(),"UTF-8");//同样注意这里求长度用的也是数据报
                //5.打印在控制台上
                System.out.printf("req:%s resp:%s\n",request,response);
            }
        }
    
        public static void main(String[] args) throws IOException {
            //如果服务器在其他机器上就需要将IP地址和端口号更改了
            UdpEchoClient udpEchoClient=new UdpEchoClient("127.0.0.1",9090);
            udpEchoClient.start();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    注意:当然要先启动服务器再启动客户端啦!

    好啦! 以上就是对 UDP Socket编程的讲解,希望能帮到你 !
    评论区欢迎指正 !

  • 相关阅读:
    4.2.2-测试应用程序平台配置
    Yii使用queue实现队列
    JS的Proxy
    Redis的缓存穿透,缓存击穿,缓存雪崩
    Code For Better 谷歌开发者之声——谷歌Web工具包(GWT)
    数字图像处理笔记
    java-php-python-ssm旅游路线规划系统计算机毕业设计
    电脑内存不足怎么办
    Mysql计算一行最大最小值
    ffmpeg Operation not permitted
  • 原文地址:https://blog.csdn.net/m0_61832361/article/details/132915151