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

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

文章目录

I UDP 交互原理

II UDP 服务器端代码示例

III UDP 客户端代码示例

IV 服务器 客户端 运行结果



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 服务器端代码示例


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 客户端代码示例


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 服务器 客户端 运行结果


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


image.png

目录
相关文章
|
2月前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
84 9
|
3月前
|
机器学习/深度学习 人工智能 运维
企业内训|LLM大模型在服务器和IT网络运维中的应用-某日企IT运维部门
本课程是为某在华日资企业集团的IT运维部门专门定制开发的企业培训课程,本课程旨在深入探讨大型语言模型(LLM)在服务器及IT网络运维中的应用,结合当前技术趋势与行业需求,帮助学员掌握LLM如何为运维工作赋能。通过系统的理论讲解与实践操作,学员将了解LLM的基本知识、模型架构及其在实际运维场景中的应用,如日志分析、故障诊断、网络安全与性能优化等。
101 2
|
16天前
|
缓存 负载均衡 监控
HTTP代理服务器在网络安全中的重要性
随着科技和互联网的发展,HTTP代理IP中的代理服务器在企业业务中扮演重要角色。其主要作用包括:保护用户信息、访问控制、缓存内容、负载均衡、日志记录和协议转换,从而在网络管理、性能优化和安全性方面发挥关键作用。
51 2
|
2月前
|
弹性计算 监控 数据库
制造企业ERP系统迁移至阿里云ECS的实例,详细介绍了从需求分析、数据迁移、应用部署、网络配置到性能优化的全过程
本文通过一个制造企业ERP系统迁移至阿里云ECS的实例,详细介绍了从需求分析、数据迁移、应用部署、网络配置到性能优化的全过程,展示了企业级应用上云的实践方法与显著优势,包括弹性计算资源、高可靠性、数据安全及降低维护成本等,为企业数字化转型提供参考。
63 5
|
3月前
|
存储 安全 数据可视化
提升网络安全防御有效性,服务器DDoS防御软件解读
提升网络安全防御有效性,服务器DDoS防御软件解读
65 1
提升网络安全防御有效性,服务器DDoS防御软件解读
|
2月前
|
存储 关系型数据库 MySQL
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
875 2
|
3月前
|
安全 区块链 数据库
|
19天前
|
SQL 安全 网络安全
网络安全与信息安全:知识分享####
【10月更文挑战第21天】 随着数字化时代的快速发展,网络安全和信息安全已成为个人和企业不可忽视的关键问题。本文将探讨网络安全漏洞、加密技术以及安全意识的重要性,并提供一些实用的建议,帮助读者提高自身的网络安全防护能力。 ####
59 17
|
30天前
|
存储 SQL 安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将介绍网络安全的重要性,分析常见的网络安全漏洞及其危害,探讨加密技术在保障网络安全中的作用,并强调提高安全意识的必要性。通过本文的学习,读者将了解网络安全的基本概念和应对策略,提升个人和组织的网络安全防护能力。
|
1月前
|
SQL 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将从网络安全漏洞、加密技术和安全意识三个方面进行探讨,旨在提高读者对网络安全的认识和防范能力。通过分析常见的网络安全漏洞,介绍加密技术的基本原理和应用,以及强调安全意识的重要性,帮助读者更好地保护自己的网络信息安全。
49 10