chat3-Server接收数据并转发给所有Client

本文档描述了Server端接收到Client的消息并转发给所有客户端或私发给某个客户端

服务端为当前客户端创建一个线程,此线程接收当前客户端的消息并转发给所有客户端或私发给某个客户端

一、Server:

1.1.Server端添加将消息转化给客户端的代码。有用集合保存输出流,、从集合获取输出流,广播数据给所有人的方法sendMessage()、将消息发送给固定某个客户端的方法sendMessageToSomeone()

在Server端的ClientHandler线程类中添加如下代码(主要是在上一个文档的基础上添加返回消息给客户端的代码)。

1.2.run()方法上边添加一个群发消息的方法sendMessage()还有另一个私发消息的方法sendMessageToSomeOne()

/**将消息发送给所有客户端*/
public void sendMessage(String message){
    System.out.println(message);
    synchronized (allOut) {
        //同步代码块synchronized(){}作用:
     //这里要求遍历集合时与增删元素互斥,因为迭代器要求遍历过程中不可以通过集合方法增删元素
        //这里用forEach循环迭代集合时,不能调用集合的put()add()和remove()方法否则抛异常。
        //所以应该把forEach循环放入到同步代码块synchronized(){}中
        //(因为:forEach循环会编译为Iterator迭代器方式)
        //for (PrintWriter o : allOut) {
      //o.println(message);//从allOut集合中获取一个输出流o,再用输出流o的println返回数据给客户端
        //}
        //原本用List  allOut集合则用forEach循环时是直接调用的

        //换成Map allOut集合则应该先用allOut.values()方法获取所有value集合,再用forEach
        //遍历allOut的所有value
        Collection<PrintWriter> c = allOut.values();
        for(PrintWriter o : c){
            o.println(message);//从allOut集合中获取一个输出流o再用输出流o的println返回数据给客户端
        }//循环完allOut集合中的所有输出流 可以将此message返回给每个客户端
    }
}
public void sendMessageToSomeone(String message){/**私聊功能*/
    //私聊消息的格式:   @对方昵称:聊天消息
    //私聊消息格式验证:  @.+:.+      //@开头然后有一个以上的字符,然后是":" , 最后也是一个以上的字符
    //                            //@张三: 你好
    if(message.matches("@.+:.+")){
        //从私聊信息message截取到对方的昵称(从聊天消息第1个字符开始截取到":"字符的位置<第0个字符@不需要>)
        // 比如截取 "@张三: 你好"  中的"张三"
        String toNickName = message.substring(1,message.indexOf(":"));
        //截取出要发送给对方的内容(从聊天消息的":"字符的后一个位置到消息的末尾之间的所有文字)
        String toMessage = message.substring(message.indexOf(":")+1);
        //从Map allOut集合通过对方的昵称作为key,获取他对应的输出流
        PrintWriter pw = allOut.get(toNickName);
        if(pw==null){//如果没有获取到输出流,则说明对方昵称对应的用户不存在(对方下线了)
       //从Map allOut集合获取发送消息的客户端的输出流,用此println()给发送消息的客户端返回 "用户[接收方昵称]不存在!"
            allOut.get(nickName).println("用户["+toNickName+"]不存在!");
        }else {
            //如果范传奇在控制台上输入:   @王克晶:晚上有空么?
            //则"王克晶"为toNickname    "晚上有空么?" 为toMessage       
            //   最终要向王克晶发送的消息内容是: “ 范传奇悄悄对你说:晚上有空么?”
            pw.println(nickName+"悄悄对你说:"+toMessage);
            //调用saveMessage()将该消息保存到数据库中      
        }
    }else{//私聊格式错误(如果发送的消息message不是以@开头)
        //就从Map  allOut集合获取发送消息的客户端对应的输出流,用println()返回给发送消息的客户端  "私聊格式错误..."
        allOut.get(nickName).println("私聊格式错误(@对方昵称:聊天内容),请重新输入");
    }
}

二、Client端:

客户端需要编写一个单独的线程类ServerHandler,用于接收服务端返回的数据 (main方法调用的start()方法内发送消息<main线程发送消息>)  (是为了发送消息的同时还能接收消息)。

2.1.ServerHandler类

编写用于接收服务端返回的消息的线程类:

/**该线程任务负责不断地接收来自服务端返回的消息*/
private class ServerHandler implements Runnable{
    public void run() {
        try {
            //通过socket获取输入流,用于读取服务端发送过来的消息
            InputStream in = socket.getInputStream();
            InputStreamReader isr = new InputStreamReader(in, StandardCharsets.UTF_8);
            BufferedReader br = new BufferedReader(isr);
            //循环读取来自服务端发送过来的消息并输出到客户端控制台上
            String message;
            while((message = br.readLine())!=null){
                System.out.println(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.2.创建线程类对象并启动:

在Client类中的start方法中, 在打印”昵称不能为空”的下边添加如下启动线程的代码(并将此接收服务端消息的线程设置为后台线程。)

运行效果:


                                                                                                    By   zhaoyq   2024-05-31

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/846361.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI 换装之OOTDiffusion

项目地址&#xff1a;https://github.com/levihsu/OOTDiffusion 试用地址&#xff1a;https://ootd.ibot.cn/ 本地部署 下载模型 git lfs安装, 然后国内源下载 git clone https://www.modelscope.cn/AI-ModelScope/clip-vit-large-patch14.git然后国内镜像手动下载 https://…

【面试题-009】线程的生命周期和状态

文章目录 java如何创建线程继承 Thread 类使用 Runnable 接口选择继承还是实现接口 线程池的核心参数和原理核心参数原理 为什么是先添加队列 队列满了在创建最大线程&#xff1f; 在 Java 中&#xff0c;线程的生命周期包括几个不同的状态&#xff0c;这些状态可以由线程的状态…

深入Netty RPC内核:编码、通信与性能优化全指南

1.Netty 简介 1.1. Netty的优势 Netty是一个异步的、事件驱动的网络应用框架&#xff0c;用于快速开发高性能、高可靠性的服务器和客户端程序。它提供了丰富的缓冲区类型和传输抽象&#xff0c;可以让您轻松地进行直接内存操作&#xff0c;减少拷贝和内存消耗。 1.2. Netty在…

学习小记录——python函数的定义和调用

今日小好运&#xff0c;未来有好运。&#x1f381;&#x1f496;&#x1fad4; 分享个人学习的小小心意&#xff0c;一起来看看吧 函数的定义 函数通常来说就是带名字的代码块&#xff0c;用于完成具体的工作&#xff0c;需要使用的时候调用即可&#xff0c;这不仅提高代码的…

[数据集][目标检测]旋风检测数据集VOC+YOLO格式157张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;159 标注数量(xml文件个数)&#xff1a;159 标注数量(txt文件个数)&#xff1a;159 标注类别…

音频信号分析与实践

音频信号分析与实践课程,方便理解音频信号原理和过程 1.音频信号采集与播放 两种采样模式和标准的采样流程 人说话的声音一般在2kHz一下&#xff1a; 采样频率的影响&#xff1a;采样率要大于等于信号特征频率的2倍&#xff1b;一般保证信号完整&#xff0c;需要使用10倍以上的…

『大模型笔记』FlashAttention技术细节介绍!

FlashAttention技术细节介绍! 文章目录 一. FlashAttention技术介绍1. 什么是闪存注意力(FlashAttention)?1.1 自注意力在序列长度方面是平方级的1.2 在现代GPU中,计算速度实际上已经超过了内存速度,因此瓶颈实际上是内存速度而不是计算速度1.3 闪存注意力是一种面向IO的精…

unity2020打包webGL时卡进程问题

我使用的2020.3.0f1c1&#xff0c;打包发布WEB版的时候会一直卡到asm2wasm.exe这个进程里&#xff0c;而且CPU占用率90%以上。 即使是打包一个新建项目的空场景也是同样的问题&#xff0c;我尝试过一直卡在这里会如何&#xff0c;结果还真打包成功了。只是打包一个空场景需要20…

..\MYLIB\modbus.c(49): error: #84: invalid combination of type specifiers

在keil中添加相应的文件出现以下问题时 ..\MYLIB\modbus.c(49): error: #84: invalid combination of type specifiers 是由于&#xff1a;在定义的函数体的前面有一个变量类型

Ubuntu 安装 Vulkan SDK

LunarG VulkanSDK Packages 此存储库包含Ubuntu 20.04和22.04的最新SDK版本。 This repository contains the most recent SDK releases for Ubuntu 20.04 and 22.04. 有关LunarG Vulkan SDK的更多信息&#xff0c;请访问文档部分。 For more information about the LunarG V…

java web 前端开发:深入剖析与实战指南

java web 前端开发&#xff1a;深入剖析与实战指南 在当今数字化时代&#xff0c;Java Web前端开发已经成为了构建优秀用户体验的关键环节。它涉及到多个方面&#xff0c;包括界面设计、交互逻辑、性能优化等。本文将从四个方面、五个方面、六个方面和七个方面&#xff0c;对J…

iOS怎么Python?深度探索iOS平台上的Python之路

iOS怎么Python&#xff1f;深度探索iOS平台上的Python之路 在移动开发的广袤领域中&#xff0c;iOS以其独特的生态系统和严格的审核机制而闻名。然而&#xff0c;对于希望在iOS平台上使用Python进行开发的开发者来说&#xff0c;这似乎是一个颇具挑战的任务。那么&#xff0c;…

2024年西安交通大学程序设计竞赛校赛

2024年西安交通大学程序设计竞赛校赛 文章目录 2024年西安交通大学程序设计竞赛校赛D瑟莉姆的宴会E: 雪中楼I: 命令行(待补)J&#xff1a;最后一块石头的重量(待补)K: 崩坏&#xff1a;星穹铁道(待补)M&#xff1a;生命游戏N: 圣诞树 D瑟莉姆的宴会 解题思路&#xff1a; ​ …

模拟建造游戏:城市:天际线Cities: Skylines for Mac/win中文原生版

《城市&#xff1a;天际线》&#xff08;Cities: Skylines&#xff09;是一款由Colossal Order开发&#xff0c;Paradox Interactive发行的城市建设模拟游戏。这款游戏于2015年首次发布&#xff0c;迅速赢得了玩家和评论家的好评&#xff0c;并成为了备受欢迎的城市建设游戏之一…

java代码审计之fastjson反序列化漏洞

fastjson反序列化漏洞分析 Fastjson 是一个 Java 库&#xff0c;可以将 Java 对象转换为 JSON 格式&#xff0c;当然它也可以将 JSON 字符串转换为 Java 对象。Fastjson 可以操作任何 Java 对象&#xff0c;即使是一些预先存在的没有源码的对象。该产品主要提供了两个接口&…

2024.6.1每日一题

儿童节快乐&#x1f604; LeetCode 给小朋友们分糖果 I 题目链接&#xff1a;2928. 给小朋友们分糖果 I - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你两个正整数 n 和 limit 。 请你将 n 颗糖果分给 3 位小朋友&#xff0c;确保没有任何小朋友得到超过 limit 颗…

STM32作业实现(六)闪存保存数据

目录 STM32作业设计 STM32作业实现(一)串口通信 STM32作业实现(二)串口控制led STM32作业实现(三)串口控制有源蜂鸣器 STM32作业实现(四)光敏传感器 STM32作业实现(五)温湿度传感器dht11 STM32作业实现(六)闪存保存数据 STM32作业实现(七)OLED显示数据 STM32作业实现(八)触摸按…

一些通用指令和网站

1、因为很多库是国外的&#xff0c;在国内下载可能不成功或者网速很慢&#xff0c;这是可以用国内镜像网站下载 永久的修改镜像源地址&#xff1a;pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple 2、色卡查询网&#xff1a; 网页常用色彩 网页配…

Mistral大模型:Getting Started With Mistral

Getting Started With Mistral 本文是学习 https://www.deeplearning.ai/short-courses/getting-started-with-mistral/ 这门课的学习笔记。 What you’ll learn in this course In this course, you’ll access Mistral AI’s collection of open source and commercial mod…

物联网实战--平台篇之(十二)设备管理前端

目录 一、界面演示 二、设备列表 三、抖动单元格 四、设备模型 五、设备编辑 本项目的交流QQ群:701889554 物联网实战--入门篇https://blog.csdn.net/ypp240124016/category_12609773.html 物联网实战--驱动篇https://blog.csdn.net/ypp240124016/category_12631333.htm…