前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Java 网络编程】UDP 服务器 与 客户端持续交互 案例

【Java 网络编程】UDP 服务器 与 客户端持续交互 案例

作者头像
韩曙亮
发布2023-03-27 17:02:42
1.6K0
发布2023-03-27 17:02:42
举报
文章被收录于专栏:韩曙亮的移动开发专栏

文章目录

I UDP 交互原理

1. UDP 单播传输流程 : A 给 B 发送数据包 , B 设备一定要处于监听 X 端口状态 , A 向 B 的 X 端口发送数据包 , B 才能收到 ; B 收到 A 的数据包后 , B 就知道了 A 的端口号 Z 的信息了 , 此时 B 可以向 A 的 Z 端口号发送数据包 ;

2. 局域网设备交互 : A 设备给局域网其它设备发送信息 , 并能接收到其它设备回送给 A 的信息 ;

3. 接收信息设备监听 X 端口 : 此时 A 作为客户端时 , 服务器需要接收 A 发送的数据包 , 服务器需要监听一个指定的接口 X , 那么如果 A 发送广播消息 , 监听 X 端口的服务器就会收到 A 发送的消息 ;

4. A 提前监听端口 Z : 如果服务器在收到消息后立刻向 A 的 Z 端口回送一个反馈信息 , 设备 A 需要在发送消息之前就监听 Z 端口 , 才能实现上述功能 ;

5. 持续交互 : A 不断向其它设备的 X 端口发送信息 , 其它设备可以不断反馈信息给设备 A 的 Z 端口 , 这样就实现了客户端与服务器端数据交互的功能 ;

II UDP 服务器端代码示例

代码语言:javascript
复制
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.ArrayList;

public class UDPServer {

    public static void main(String[] args){

        System.out.println("服务器 开始运行");

        //开启接收数据的线程
        ReceiveThread receiveThread = new ReceiveThread();
        receiveThread.start();
    }



    /**
     * 服务器端监听客户端发送的信息
     */
    private static class ReceiveThread extends Thread{

        /**
         * 是否继续监听 , 循环控制变量
         */
        boolean isReceive = true;

        /**
         * 存储发送数据的客户端信息
         */
        ArrayList<Client> clients = new ArrayList<>();

        @Override
        public void run() {
            super.run();

            try {
                //I. 创建 DatagramSocket 对象 , 用于 UDP 数据包的发送和接收


                //1. UDP 数据包接收者 , 监听 8888 端口
                //      该 DatagramSocket 既可以接收数据包 , 也可以发送数据包
                DatagramSocket datagramSocket = new DatagramSocket(8888);


                //II. 接收 UDP 数据包 , 无限循环接收来自客户端的信息 , 并根据不同的信息进行不同处理


                while (isReceive){

                    //2. 接收数据包使用的缓冲区
                    byte[] receiveBuffer = new byte[256];
                    //3. 接收 UDP 数据包使用的 DatagramPacket 对象
                    DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);

                    //4. 接收 UDP 数据包
                    datagramSocket.receive(receivePacket);

                    //5. 获取发送端的 IP 地址
                    String sendIP = receivePacket.getAddress().getHostAddress();
                    //6. 获取发送端的端口号
                    int sendPort = receivePacket.getPort();
                    //7. 获取接收到的数据的长度
                    int receiveLen = receivePacket.getLength();
                    //8. 获取接收到的数据 , 并转为字符串
                    String receiveData = new String(receivePacket.getData(), 0, receiveLen);
                    //9. 打印接收到的数据包信息
                    System.out.println("服务器 接收到 " + sendIP + " : " + sendPort + " 发送的数据 : " + receiveData);

                    //将客户端信息发送到



                    //III. 发送 UDP 数据包


                    //10. 将接收到的数据长度回送给发送者
                    String response = "服务器端 收到客户端发送的 " + receiveLen + " Byte 数据";
                    //11. 将字符串转为 byte[] 数组
                    byte[] responseData = response.getBytes();
                    //12. 创建发送数据包 , 需要传入的参数 1> 数据 2> 数据长度 3> 接收者的地址 4> 接收者的端口号
                    DatagramPacket responsePacket = new DatagramPacket(responseData, responseData.length,
                            receivePacket.getAddress(), receivePacket.getPort());

                    //13. 将数据包发送出去
                    datagramSocket.send(responsePacket);

                    System.out.println("服务器 向客户端 " + sendIP + " : " + sendPort + " 发送的数据 : " + response);

                    //退出服务器循环
                    if("exit".equals(receiveData)){
                        isReceive = false;
                    }

                }


            } catch (SocketException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                System.out.println("服务器 运行结束");
            }
        }
    }

    /**
     * 封装向服务器端发送数据的客户端信息
     * 主要是保存客户端的 IP 地址和端口号
     */
    private static class Client{
        String ClientIP;
        String ClientPort;

        public Client(String clientIP, String clientPort) {
            ClientIP = clientIP;
            ClientPort = clientPort;
        }
    }

}
III UDP 客户端代码示例

代码语言:javascript
复制
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class UDPClient {

    public static void main(String[] args){

        try {
            System.out.println("客户端 开始运行");


            //I. 创建 DatagramSocket 对象 , 用于 UDP 数据包的发送和接收


            //1. UDP 数据包套接字 , 客户端 ,
            //      监听 8889 端口 , 发送和接收数据包都使用该端口
            DatagramSocket datagramSocket = new DatagramSocket(8889);


            //II. 人机交互控制台阻塞获取用户输入


            //1. 获取控制台输入流
            InputStream is = System.in;
            //2. 该输入流会阻塞 , 等待用户控制台输入
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            // 循环控制变量 , 循环发送和接收 UDP 数据包
            boolean flag = true;
            while(flag){

                //3. 阻塞命令行 , 等待用户输入一行数据, 并存入 string 对象中
                String string = br.readLine();


                //III. 向服务器发送 UDP 数据包


                //1. 将字符串转为 byte[] 数组
                byte[] sendData = string.getBytes();
                //2. 创建发送数据包 , 需要传入的参数 1> 数据 2> 数据长度 3> 接收者的地址 4> 接收者的端口号
                //      向服务器端发送数据 , 发送的端口是自动分配的
                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,
                        InetAddress.getLocalHost(), 8888);
                //3. 将数据包发送出去
                datagramSocket.send(sendPacket);

                System.out.println("客户端 向服务器 : " +
                        InetAddress.getLocalHost() + " : " + 8888 + " 发送的数据 : " + string);

                //4. 退出
                if("exit".equals(string)){
                    flag = false;
                }


                //IV. 接收服务器反馈的 UDP 数据包


                //1. 接收数据包使用的缓冲区
                byte[] receiveBuffer = new byte[1024];
                //2. 接收 UDP 数据包使用的 DatagramPacket 对象
                DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);

                //3. 接收 UDP 数据包
                datagramSocket.receive(receivePacket);

                //4. 获取发送端的 IP 地址
                String sendIP = receivePacket.getAddress().getHostAddress();
                //5. 获取发送端的端口号
                int sendPort = receivePacket.getPort();
                //6. 获取接收到的数据的长度
                int receiveLen = receivePacket.getLength();
                //7. 获取接收到的数据 , 并转为字符串
                String receiveData = new String(receivePacket.getData(), 0, receiveLen);
                //8. 打印接收到的数据包信息
                System.out.println("客户端 接收到服务器端反馈信息 : " +
                        sendIP + " : " + sendPort + " 发送的数据 : " + receiveData);

            }

        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            System.out.println("客户端 运行结束");
        }
    }

}
IV 服务器 客户端 运行结果

先运行服务器端 , 再运行客户端 ;

在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-08-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
    • I UDP 交互原理
      • II UDP 服务器端代码示例
        • III UDP 客户端代码示例
          • IV 服务器 客户端 运行结果
          相关产品与服务
          腾讯云小微
          腾讯云小微,是一套腾讯云的智能服务系统,也是一个智能服务开放平台,接入小微的硬件可以快速具备听觉和视觉感知能力,帮助智能硬件厂商实现语音人机互动和音视频服务能力。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档