java网络之基于UDP的聊天程序示例解析

下面是关于 "java网络之基于UDP的聊天程序示例解析" 的完整攻略:

一、背景介绍

Java编程过程中,网络编程是非常重要的一部分。UDP协议是Java中常用的一种协议,其具有数据传输快、连接简单等特点,非常适合一些及时性要求不高的网络应用,比如聊天室程序等。本篇攻略就是针对基于UDP协议的聊天程序的编写,进行详细的解析。

二、程序设计思路

本程序的设计思路可以归纳为如下几个步骤:

  1. 客户端与服务器端都使用UDP协议进行数据的传输与接收。
  2. 客户端之间的通信需要通过服务器进行转发。
  3. 客户端与服务器之间,以及客户端之间,都需要确立好唯一的通讯对象,以进行数据的传输。
  4. 对于向服务器端发送的数据,需要使用线程池进行优化。

三、程序示例解析

示例1:服务器端代码

public class ChatServer {
    // 维护所有在线的客户端
    private static Map<String, SocketAddress> onlineClients = new ConcurrentHashMap<String, SocketAddress>();

    public static void main(String[] args) throws Exception {
        // 创建DatagramSocket,监听1024端口
        DatagramSocket server = new DatagramSocket(1024);
        byte[] buf = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buf, buf.length);
        System.out.println("服务器已启动!");
        while (true) {
            // 接收客户端发来的消息
            server.receive(packet);
            // 解析收到的消息
            String message = new String(packet.getData(), 0, packet.getLength(), "UTF-8");
            String[] arr = message.split(":");
            if (arr.length == 2) {
                // 收到客户端的上线请求
                String name = arr[1];
                onlineClients.put(name, packet.getSocketAddress());
                // 向该客户端反馈上线成功的消息
                String msg = "sys: welcome " + name + " online!";
                byte[] responseBuf = msg.getBytes("UTF-8");
                DatagramPacket responsePacket = new DatagramPacket(responseBuf, responseBuf.length, packet.getAddress(), packet.getPort());
                server.send(responsePacket);
            } else if (arr.length == 3) {
                // 收到客户端的消息,请求转发到指定客户端
                String from = arr[0];
                String to = arr[1];
                String content = arr[2];
                SocketAddress toAddress = onlineClients.get(to);
                String msg = from + ":" + content;
                byte[] responseBuf = msg.getBytes("UTF-8");
                DatagramPacket responsePacket = new DatagramPacket(responseBuf, responseBuf.length, toAddress);
                server.send(responsePacket);
            }
        }
    }
}

以上是服务器端的主要代码逻辑,主要实现了接收客户端消息,处理客户端上下线请求,转发消息等功能。

示例2:客户端代码

public class ChatClient {
    private static String name;
    private static SocketAddress serverAddress;
    private static DatagramSocket client;
    private static ExecutorService threadPool = Executors.newSingleThreadExecutor();

    public static void main(String[] args) throws Exception {
        // 设定服务器地址
        serverAddress = new InetSocketAddress("127.0.0.1", 1024);
        // 创建DatagramSocket
        client = new DatagramSocket();
        System.out.println("请输入你的名字:");
        Scanner scanner = new Scanner(System.in);
        name = scanner.nextLine();
        // 向服务器发送上线请求
        String message = "login:" + name;
        byte[] buf = message.getBytes("UTF-8");
        DatagramPacket packet = new DatagramPacket(buf, buf.length, serverAddress);
        client.send(packet);
        threadPool.execute(new ReceiveMessageTask());
        // 发送消息给其他在线客户端
        while (true) {
            String line = scanner.nextLine();
            if (StringUtils.isEmpty(line)) continue;
            String[] arr = line.split(":");
            if (arr.length == 2) {
                String to = arr[0];
                String content = arr[1];
                String message2 = name + ":" + to + ":" + content;
                byte[] buf2 = message2.getBytes("UTF-8");
                SocketAddress toAddress = onlineClients.get(to);
                if (toAddress != null) {
                    DatagramPacket packet2 = new DatagramPacket(buf2, buf2.length, toAddress);
                    client.send(packet2);
                } else {
                    System.out.println("用户 " + to + " 不在线");
                }
            } else {
                System.out.println("格式不正确,正确格式为:[对方用户名]:[消息内容]");
            }
        }
    }

    static class ReceiveMessageTask implements Runnable {
        @Override
        public void run() {
            while (true) {
                try {
                    byte[] buf = new byte[1024];
                    DatagramPacket packet = new DatagramPacket(buf, buf.length);
                    client.receive(packet);
                    String message = new String(packet.getData(), 0, packet.getLength(), "UTF-8");
                    System.out.println(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

以上是客户端的主要代码逻辑,主要实现了登录请求的发送,消息的发送,消息的接收等功能。

四、总结

以上就是基于UDP协议的聊天程序示例解析的相关内容,通过本攻略的学习,读者可以了解基于UDP协议进行数据传输的流程和步骤,以及Java中的相关网络编程知识。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java网络之基于UDP的聊天程序示例解析 - Python技术站

(0)
上一篇 2023年5月30日
下一篇 2023年5月30日

相关文章

  • Spring Boot+Jpa多数据源配置的完整步骤

    下面是Spring Boot+Jpa多数据源配置的完整攻略: 配置文件 首先需要在application.properties 或者 application.yml 配置文件中进行多数据源的配置。示例如下: # 数据源 1 spring.datasource.first.url=jdbc:mysql://localhost:3306/first_databa…

    Java 2023年5月20日
    00
  • SpringMVC详解如何映射请求数据

    下面我将详细讲解SpringMVC如何映射请求数据的完整攻略。 什么是SpringMVC SpringMVC是一种基于Java的Web框架,它可以帮助我们实现Web应用程序的开发。它是Spring Framework的一部分,专门用于处理Web请求和响应。SpringMVC基于模型-视图-控制器(MVC)架构模式,将应用程序分为模型、视图和控制器三个组件。 …

    Java 2023年6月15日
    00
  • 什么是本地方法栈?

    本地方法栈(Native Method Stack)是一种用于存储本地方法的内存区域。本地方法是指本地语言(如 C 或 C++)编写方法,可以通过 Java Native Interface(JNI)调用。本地方法栈是线程私有的其大小可以通过 -Xss进行设置。 使用本地栈,需要注意以下几点: 在程序开发中需要合理使用存,避免出现栈溢出等问题。 在使用 JN…

    Java 2023年5月12日
    00
  • Javacsv实现Java读写csv文件

    以下是Javacsv实现Java读写csv文件的完整攻略: 1. 什么是Javacsv Javacsv 是一个Java编程语言的CSV(逗号分隔符)文件格式库,可以和 Java 一起使用来读取和写入以逗号为分隔符的文件。 Javacsv 旨在提供一个易于使用的、稳定的、高效的方式来处理大型、小型和复杂的 CSV 文件。 2. Javacsv的安装 Javac…

    Java 2023年5月20日
    00
  • 图解Java经典算法冒泡选择插入希尔排序的原理与实现

    图解Java经典算法冒泡选择插入希尔排序的原理与实现 什么是排序算法? 排序算法是计算机科学中的一类基本算法,它将一个乱序的数据序列按照一定的规则重新排列,使得排序后的序列满足特定的要求。 常见的排序方法包括冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序等。 冒泡排序的原理和实现 冒泡排序是一种简单的排序算法,其基本思想是从小到大依次比较相邻的两…

    Java 2023年5月19日
    00
  • SpringMvc返回modelandview返回的页面无法跳转问题及解决

    当使用Spring MVC中的ModelAndView返回页面时,有时页面无法正常跳转,这种问题通常是由于Spring MVC配置不正确导致的。下面是解决此类问题的完整攻略: 1. 确认控制器方法返回类型和视图名称 在控制器方法中,应该返回一个ModelAndView类型的对象,在这个对象中设置好要跳转的视图名称和需要传递给视图的模型数据。 示例如下: @R…

    Java 2023年6月15日
    00
  • SpringBoot深入分析webmvc和webflux的区别

    下面是关于“SpringBoot深入分析webmvc和webflux的区别”的完整攻略,包含两个示例说明。 SpringBoot深入分析webmvc和webflux的区别 SpringBoot是一个流行的Java开发框架,它提供了许多功能和特性来简化Java应用程序的开发。其中,SpringBoot的Web框架有两种选择:webmvc和webflux。本文将…

    Java 2023年5月17日
    00
  • Spring Security配置保姆级教程

    针对“Spring Security配置保姆级教程”的完整攻略,以下是详细的讲解: 前言 Spring Security 是一个基于 Spring 框架的安全模块,为Spring应用提供了声明式的安全访问控制。本文将详细讲解 Spring Security 的配置,帮助初学者掌握 Spring Security 的使用方法。 基本概念 在使用 Spring …

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部