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,一经查实,立即删除!

相关文章

学习小记录——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倍以上的…

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;在定义的函数体的前面有一个变量类型

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;即使是一些预先存在的没有源码的对象。该产品主要提供了两个接口&…

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

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

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…

Java利用POI绘制表格

前提需求 最近公司要求写一些记录的表格&#xff0c;并且带有导出功能。再深入学习后&#xff0c;表格的底层其实就是list遍历塞值&#xff0c;导出功能的话可以由前端&#xff0c;后端实现&#xff0c;但技多不压身嘛&#xff0c;这里我自己就写了后端的导出功能&#xff0c;…

day-37 电话号码的字母组合

思路 设置一个char型的二维数组&#xff0c;每次从号码对应的子母中选出一个&#xff0c;拼接在一起即可 解题方法 注意&#xff1a;有的数字对应三个字母&#xff0c;有的对应四个字母 Code class Solution {public char arr[][]{{a,b,c, },{d,e,f, },{g,h,i, },{j,k,l, },…

虚拟现实环境下的远程教育和智能评估系统(三)

本周继续进行开发工具的选择与学习&#xff0c;基本了解了以下技术栈的部署应用&#xff1b; 一、Seata&#xff1a; Seata&#xff08;Simple Extensible Autonomous Transaction Architecture&#xff09;是一款开源的分布式事务解决方案&#xff0c;旨在提供高性能和简单易…

力扣575. 分糖果

题目&#xff1a; Alice 有 n 枚糖&#xff0c;其中第 i 枚糖的类型为 candyType[i] 。Alice 注意到她的体重正在增长&#xff0c;所以前去拜访了一位医生。 医生建议 Alice 要少摄入糖分&#xff0c;只吃掉她所有糖的 n / 2 即可&#xff08;n 是一个偶数&#xff09;。Alic…

智能监控技术助力山林生态养鸡:打造智慧安全的养殖新模式

随着现代科技的不断发展&#xff0c;智能化、自动化的养殖方式逐渐受到广大养殖户的青睐。特别是在山林生态养鸡领域&#xff0c;智能化监控方案的引入不仅提高了养殖效率&#xff0c;更有助于保障鸡只的健康与安全。视频监控系统EasyCVR视频汇聚/安防监控视频管理平台在山林生…

攻防世界---misc---心仪的公司

1、题目描述 2、下载附件是一个流量包 方法一&#xff1a; 1、用winhex分析&#xff0c;ctrlf搜索flag 2、尝试将搜索到的flag拿去提交&#xff0c;但是不对 3、担心flag不是长flag&#xff0c;做题多了你就会发现有些flag会是fl4g这种&#xff0c;为了可以稍微全面一点&…

6.2 休息日 背包问题总结

就目前所遇到的01背包与完全背包作总结。 01背包 有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品只能用一次&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 二维dp数组01背包 动规五部曲 1.确定…

IO流(2)

缓冲流 字节缓冲流 利用字节缓冲区拷贝文件&#xff0c;一次读取一个字节&#xff1a; public class test {public static void main(String [] args) throws IOException {//利用字节缓冲区来拷贝文件BufferedInputStream bisnew BufferedInputStream(new FileInputStream(&…

STM32作业实现(四)光敏传感器

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