8.1UDP点对点聊天小项目

这个Java项目实现了一个基于UDP协议的点对点聊天程序,支持双向消息发送和接收。程序通过命令行参数配置远程IP、远程端口和本地端口,默认值为127.0.0.1、12345和8888。核心功能包括:使用DatagramSocket和DatagramPacket进行UDP通信,多线程处理接收数据以避免阻塞主线程,以及通过ThreadControl类控制线程生命周期。程序支持UTF-8编码的消息传输,并使用GBK编码读取控制台输入

复制代码
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.Charset;
import java.util.Scanner;

class ThreadControl {
    // 使用 volatile 修饰变量
    volatile boolean running = true;
}

public class Test3 {
    public static void main(String[] args) {
        // 默认远程IP地址和端口,以及本地端口
        String remoteIp = "127.0.0.1";
        int remotePort = 12345;
        int localPort = 8888;
    
        // 如果提供了命令行参数,则使用参数值覆盖默认值
        if (args.length == 3) {
            remoteIp = args[0];
            remotePort = Integer.parseInt(args[1]);
            localPort = Integer.parseInt(args[2]);
        }
    
        try {
            // 获取服务器地址
            InetAddress serverAddress = InetAddress.getByName(remoteIp);
            // 创建本地 DatagramSocket 实例,绑定到指定的本地端口
            DatagramSocket socket = new DatagramSocket(localPort);
    
            // 创建线程控制对象
            ThreadControl control = new ThreadControl();
    
            // 创建并启动接收数据的线程
            Thread receiveThread = new Thread(() -> {
                while (control.running) {
                    try {
                        // 准备接收数据的缓冲区和数据包
                        byte[] receiveData = new byte[1024];
                        DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                        // 接收数据包
                        socket.receive(receivePacket);
    
                        // 将接收到的数据转换为字符串并打印
                        String response = new String(receivePacket.getData(), 0, receivePacket.getLength(),"UTF-8");
                        System.out.println(receivePacket.getAddress().toString() + ":" + receivePacket.getPort() + " 发送数据: " + response);
                    } catch (IOException e) {
                        // 只有在程序运行时才打印异常堆栈信息
                        if (control.running) {
                            e.printStackTrace();
                        }
                    }
                }
            });
            receiveThread.start();
    
            // 创建 Scanner 对象以读取控制台输入
            Scanner scanner = new Scanner(new InputStreamReader(System.in, Charset.forName("GBK")));
            while (true) {
                // 提示用户输入消息
                System.out.println("请输入要发送给客户端的消息:");
                String userInput = scanner.nextLine();
                System.out.println(userInput);
                // 如果用户输入 "exit",则退出循环
                if (userInput.equals("exit")) {
                    break;
                }
    
                // 将用户输入的消息转换为字节数组
                byte[] sendData = userInput.getBytes("UTF-8");
                try {
                    // 创建数据包并发送
                    DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, serverAddress, remotePort);
                    socket.send(sendPacket);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            // 停止接收线程
            control.running = false;
            receiveThread.interrupt(); // 可选:强制中断阻塞中的线程
    
            // 关闭资源
            scanner.close();
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

使用说明

  1. 两个人点对点聊天,通过java Test3 对方IP 对方端口 本地端口 启动程序
  2. 另一边也是同样的,通过java Test3 对方IP 对方端口 本地端口 启动程序
  3. 两个人就实现了点对点 upd 通信
  4. 输入 "exit" 可以退出。

这个 Java 小项目实现了一个基于 UDP 协议的简单聊天程序,支持接收和发送消息。以下是该项目的简要总结:

1. 功能概述

  • UDP 通信 :使用 DatagramSocket 和 DatagramPacket 实现了基于 UDP 的网络通信。
  • 双向交互:程序可以同时接收远程主机的消息,并向远程主机发送用户输入的消息。
  • 命令行参数支持:允许通过命令行传入远程 IP、远程端口和本地端口以覆盖默认配置。

2. 关键技术点

  • 多线程处理 :
    • 使用单独的线程(receiveThread)持续监听并接收数据,避免阻塞主线程。
    • 使用 ThreadControl 类中的 volatile boolean running 控制线程生命周期。
  • 字符编码处理 :
    • 发送端使用 UTF-8 编码将字符串转为字节流。
    • 接收端也使用 UTF-8 解析收到的数据包。
    • 控制台输入使用 GBK 编码读取(适配 Windows控制台 环境)。
  • 异常处理机制 :
    • 对 IOException 进行捕获,并在程序退出时选择性地打印异常信息。

3. 核心类/对象说明

  • ThreadControl:用于控制接收线程的运行状态,其中 running 是 volatile 变量,确保线程间可见性。
  • DatagramSocket:代表本地 UDP 套接字,用于接收和发送数据包。
  • Scanner:用于从控制台读取用户输入。
  • InetAddress:表示远程服务器的地址。

4. 使用说明

  • 启动方式:

    java Test3 [remoteIp remotePort localPort]

    如果不提供参数,则使用默认值:

    • remoteIp = "127.0.0.1"
    • remotePort = 12345
    • localPort = 8888
  • 操作流程:

    • 启动后自动开始监听本地端口。
    • 用户可在控制台输入消息发送给远程主机。
    • 输入 exit 结束程序。

5. 适用场景

适用于简单的局域网内设备调试或测试用途的 UDP 通信程序,具有良好的可读性和可扩展性。

相关推荐
贞明电子3 小时前
工业三色报警灯怎么接入项目系统?开关量与RS485控制应用指南
运维·网络·微信公众平台·贞明电子
学长毕设4 小时前
基于SpringBoot的实验室资产管理系统
java·spring boot·后端
HideF4 小时前
Linux
linux·服务器·网络
万联WANFLOW4 小时前
海外网络故障怎么排查?Cloudflare 三季度断网报告解读与 mtr 实战
运维·网络·故障分析
听风说ml4 小时前
socket编程 【C语言】
c语言·udp·tcp·socket编程
sbjdhjd4 小时前
网工进阶笔记:H3CSE 园区网全栈技术与协议汇总
网络·笔记·云计算·ssh·网络工程·vlan·aaa
zzu123zsw5 小时前
从臃肿的模板调用到声明式契约:深入 UniHttp 动态代理与多渠道生命周期扩展
java·spring boot·microsoft·unihttp
源码集结号6 小时前
云诊所门诊系统源码,基于SpringBoot+Vue.js架构,支持多租户设计与Docker容器化部署
java·spring boot·源码·医院信息系统·门诊系统·诊所系统
论文复现现场6 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
taktok_ai6 小时前
用 cc-switch 连接 Taktok
网络