Java实现ChatRoom

article/2025/10/23 8:22:18

基于连接通信Socket、多线程的Java聊天室

1、开发环境:

IDEA2018.1+JDK1.8

2、实现功能:

实现了模拟登录注册、群聊、私聊、显示当前在线人数列表;

在发送信息时,会向对方发送者及显示发送时间;

显示在线人数列表时,也会显示查询时间;

实现了多线程发送消息、接收消息过程。

3、代码解析(源码可见本篇博客最后):

1)客户端源码解析

客户端使用两个线程操作

一个读线程:创建客户端输入流,while循环将读到的信息输出道控制台,模拟一直等待监听输入的情况;

一个写线程:创建客户端输出流,while循环获取用户从控制台输入的内容,若用户输入的信息中包含"bye",则关闭流并且关闭该用户的Socket,此时退出while循环,写线程结束;此时读线程的if条件判断就会执行break;while循环停止,读线程结束。

2)服务器源码解析

利用Executors类创建固定大小为20的线程池(实现多线程);

使用Map集合来存储用户信息,<String, Socket>:用户名,客户端的socket;Map集合使用子类ConcurrentHashMap来实例化,保证线程安全(主要可见Java集合总结);

使用内部类来处理客户端的连接与发送信息;

根据控制台约束信息进行用户注册、私发、群聊等等功能的实现

3)两台计算机之间使用套接字建立TCP连接过程

服务器实例化一个ServerSocket对象,new ServerSocket(6666):表示是通过服务器上的6666端口进行通信;

服务器调用ServerSocket类的accept(),该方法阻塞式等待客户端的连接;

客户端实例化一个Socket对象,new Socket("127.0.0.1", 6666):指定服务器名称和端口号来请求连接,该构造方法试图将客户端连接到指定的服务器和端口号,如果通信建立,则会在客户端创建Socket对象能够与服务器进行通信;

在服务端,accept()方法返回客户端的socket对象。

4、结果展示:

开启了三个客户端

测试:   用户上线功能、显示当前用户列表功能、私聊功能、用户下线功能

客户端3

测试:   用户上线功能、显示当前用户列表功能、群聊功能

客户端2

测试:   用户上线功能、显示当前用户列表功能、群发功能、私聊功能

客户端1

服务端:体现出了用户上线及用户下线的情况

服务端

客户端源代码:

//读线程
class ReadThread implements Runnable{private Socket client;public ReadThread(Socket client) {this.client = client;}@Overridepublic void run() {try{Scanner in = new Scanner(client.getInputStream());while(true){if(in.hasNextLine()){System.out.println(in.nextLine());}if(client.isClosed()){break;}}} catch (IOException e) {e.printStackTrace();}}
}//写线程
class WriteThread implements Runnable{private Socket client;public WriteThread(Socket client) {this.client = client;}@Overridepublic void run() {try {PrintStream out = new PrintStream(client.getOutputStream(),true, "UTF-8");Scanner scanner = new Scanner(System.in);String str = "";while(true){System.out.println("在此输入:");if(scanner.hasNextLine()){str = scanner.nextLine();out.println(str);}if(str.contains("bye")){scanner.close();out.close();client.close();break;}}} catch (IOException e) {e.printStackTrace();}}
}public class MutilThreadClient {public static void main(String[] args) {try {Socket client = new Socket("127.0.0.1", 6666);Thread readThread = new Thread(new ReadThread(client));Thread writeThread = new Thread(new WriteThread(client));readThread.start();writeThread.start();} catch (IOException e) {e.printStackTrace();}}
}

服务器源代码:

public class MutilThreadServer {//使用Map的K,V存储用户信息(用户名,socket),模拟登陆现象private static Map<String, Socket> clientMap = new ConcurrentHashMap<String, Socket>();//线程安全//内部类,处理客户端private static class ExecuteClient implements Runnable{private Socket client;private ExecuteClient(Socket client) {this.client = client;}//构造注入客户端socket//返回给客户端信息时间SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");@Overridepublic void run() {try {//获取输入流Scanner in = new Scanner(client.getInputStream());String str = "";while(true){if(in.hasNextLine()){str = in.nextLine();//windows下将默认的换行\r\n中的\r替换为空字符串Pattern pattern = Pattern.compile("\r");Matcher matcher = pattern.matcher(str);str = matcher.replaceAll("");//聊天室实现的功能//用户上线:// user:123if(str.startsWith("user")){String user = str.split("\\:")[1];register(user, client);continue;}//群聊:// G:发送内容if(str.startsWith("G")){String text = str.split("\\:")[1];String user = getUser(client);if(user == ""){continue;}groupChat(text, user);continue;}//私聊//P-sendUser:textif(str.startsWith("P")){String sendUser = str.split("\\-")[1].split("\\:")[0];String text = str.split("\\-")[1].split("\\:")[1];String user = getUser(client);if(user == ""){continue;}privateChat(sendUser, text, user);continue;}//查看当前用户在线列表//用户输入ls:显示当前在线人数if(str.equals("ls")){PrintStream out = new PrintStream(client.getOutputStream(),true, "UTF-8");out.println("当前在线用户列表如下  " + sdf.format(System.currentTimeMillis()));for(String key : clientMap.keySet()){out.println(" · 用户" + key);}out.println(" · 当前在线人数:" + clientMap.size());continue;}//用户下线if(str.contains("bye")){String user = getUser(client);System.out.println("用户" + user + "下线了.....");clientMap.remove(user);continue;}}}} catch (IOException e) {e.printStackTrace();}}//通过客户端socket获取用户名private String getUser(Socket client) {String user = "";for(String key : clientMap.keySet()) {if (clientMap.get(key).equals(client)) {user =  key;}}if(user == ""){try {PrintStream out = new PrintStream(client.getOutputStream(),true, "UTF-8");out.println("当前您还未注册,请先注册!");} catch (IOException e) {e.printStackTrace();}}return user;}//注册实现private void register(String user, Socket client) {System.out.println("用户"+user+"上线了.......");clientMap.put(user, client);System.out.println("当前群聊人数为" + clientMap.size() + "人");//告知用户注册成功try {PrintStream out = new PrintStream(client.getOutputStream(),true, "UTF-8");out.println("注册成功!");} catch (IOException e) {System.err.println("注册异常:" + e);}}//群聊实现private void groupChat(String text, String user) {Set<Entry<String, Socket>> clientSet = clientMap.entrySet();for (Entry<String, Socket> entry : clientSet) {try {PrintStream out = new PrintStream(entry.getValue().getOutputStream(),true, "UTF-8");out.println("用户" + user + "  " + sdf.format(System.currentTimeMillis()));out.println("   群发:" + text);} catch (IOException e) {System.err.println("群聊异常:" + e);}}}//私聊实现private void privateChat(String sendUser, String text, String user) {try {PrintStream out = new PrintStream(clientMap.get(sendUser).getOutputStream(),true, "UTF-8");out.println("用户" + user + "  " + sdf.format(System.currentTimeMillis()));out.println("   私发:"+ text);} catch (IOException e) {e.printStackTrace();}}}public static void main(String[] args) throws Exception{//利用Exectors工具类创建固定大小线程池ExecutorService executorService = Executors.newFixedThreadPool(20);//创建服务端SocketServerSocket serverSocket = new ServerSocket(6666);for(int i = 0; i < 20; ++i){System.out.println("等待客户端链接.........");Socket client = serverSocket.accept();System.out.println("有新的客户端连接,端口号为" + client.getPort());//向线程池提交线程executorService.submit(new ExecuteClient(client));}executorService.shutdown();serverSocket.close();}
}

 整体概括

 


http://chatgpt.dhexx.cn/article/JCG4k7eh.shtml

相关文章

Java聊天室

项目介绍&#xff1a; Java聊天室是期末设计&#xff0c; 阿里巴巴druidmysql多线程GUImvn项目java Socket 服务端模块&#xff1a;踢出聊天室&#xff1a;管理员可以踢出发言不当的用户。只有当开启服务端的时候&#xff0c;客户端才能起到作用。 客户端模块&#xff1a; 注册…

用Java实现简易聊天室

说明&#xff1a;如果一个 类&#xff0c;需要有界面的显示&#xff0c;那么该类就需要继承自JFrame&#xff0c;此时&#xff0c;该类就可以被称为一个“窗体类"。 服务端代码&#xff1a; package cn.qy.chat;import javax.swing.*; import java.awt.*; import java.aw…

微信小程序购物车功能实现(干货满满)

微信小程序定制好看的购物车页面&#xff0c;实现购物车功能&#xff0c;希望对您有所帮助&#xff01; 1. 应用场景 2. 思路分析 3. 代码分析 4. 具体实现代码 效果截图&#xff1a; 1.应用场景 适用于商城、秒杀、商品购买等类型的小程序&#xff0c;负责将顾客浏览的商…

微信小程序微商城(八):缓存实现商品购物车功能

IT实战联盟博客&#xff1a;http://blog.100boot.cn 上一篇&#xff1a;微信小程序微商城&#xff08;七&#xff09;&#xff1a;动态API实现商品分类 看效果 购物车.gif 开发计划 1、商品详情页将商品信息放入缓存 2、购物车页面读取缓存获取商品信息 3、购物车商品计算…

微信小程序开发一个小型商城(六、购物车页面)

上一篇文章&#xff1a;微信小程序开发一个小型商城&#xff08;五、商品详情&#xff09; 当我们在商品详情界面中点击添加购物后&#xff0c;会跳转到购物车界面&#xff0c;购物车界面是一个tabbar&#xff0c;在跳转的时候需要加上ope-type。看下购物车的静态页面把&#x…

微信小程序实现一个购物车页面的简易列表效果

本文只是简单的模仿天猫APP的购物车列表的样式效果&#xff0c;并实现了部分事件功能&#xff0c;功能并不完善&#xff0c;请降低期待观看。 天猫APP的购物车效果&#xff1a; 小程序模仿的实现效果&#xff1a; wxml部分的代码&#xff1a; <view wx:if"{{!isCartEmp…

【Python之pymysql库学习】一、分析fetchone()、fetchmany()、fetchall()(保姆级图文+实现代码)

目录 实现效果实现思路实现代码总结 欢迎关注 『Python之pymysql库学习』 系列&#xff0c;持续更新中 欢迎关注 『Python之pymysql库学习』 系列&#xff0c;持续更新中 实现效果 实现思路 其实有半数代码是创建数据库和创建数据表并插入数据这些环境配置部分我都写好了&…

fetchone、fetchall

fetchone(): 该方法获取下一个查询结果集。结果集是一个对象,读取一行结果&#xff0c;读取完指向下一行&#xff0c;到空为止 fetchall():接收全部的返回结果行&#xff0c;到空为止 fetchone() &#xff1a; 返回单个的元组&#xff0c;也就是一条记录(row)&#xff0c;如果没…

python fetchall方法_Python连接MySQL并使用fetchall()方法过滤特殊字符

python3.3从mysql里取出的数据莫名其妙有括号和逗号每天跟自己喜欢的人一起&#xff0c;通电话&#xff0c;旅行&#xff0c;重复一个承诺和梦想&#xff0c;听他第二十八次提起童年往事&#xff0c;每年的同一天和他庆祝生日&#xff0c;每年的情人节圣诞节除夕&#xff0c;也…

pdo fetchAll

作用 fetchAll()方法是获取结果集中的所有行.其返回值是一个包含结果集中所有数据的二维数组。 PDOStatement::fetchAll ([ int $fetch_style [, mixed $fetch_argument[, array$ctor_args array() ]]] ) fetch_style:控制结果的返回方式 PDO::FETCH_ASSOC 关联数组形式 PD…

记录一个常用函数fetchall()的使用过程

fetchall() 作用是返回多个元组&#xff0c;即对应数据库里的多条数据概念&#xff1b; 常见用法是 cursor.execute(‘select * from table’) value cursor.fetchall() 此时&#xff0c;print(value)则会输出以下二维元组&#xff0c;如下图 拓展&#xff1a; 同类函数fet…

Python从Oracle数据库中获取数据——fetchall(),fetchone(),fetchmany()函数功能分析

Python从Oracle数据库中获取数据——fetchall(),fetchone(),fetchmany()函数功能分析 一、fetchall()&#xff0c;fetchone()&#xff0c;fetchmany()简单介绍 1、fetchall()函数,它的返回值是多个元组,即返回多个行记录,如果没有结果,返回的是() 2、fetchone()函数,它的返回…

KITTI数据集可视化(一):点云多种视图的可视化实现

如有错误&#xff0c;恳请指出。 在本地上&#xff0c;可以安装一些软件&#xff0c;比如&#xff1a;Meshlab&#xff0c;CloudCompare等3D查看工具来对点云进行可视化。而这篇博客是将介绍一些代码工具将KITTI数据集进行可视化操作&#xff0c;包括点云鸟瞰图&#xff0c;FOV…

KITTI数据集的点云格式转PCD格式

参考文章&#xff1a;https://blog.csdn.net/xinguihu/article/details/78922005 KITTI数据集应该不用多做介绍了&#xff0c;基本上做自动驾驶的都知道这个东西。最近本人用到这个数据集想看看里面的点云长什么模样&#xff0c;却发现有点别扭&#xff0c;没有直接可以看的工…

使用kitti数据集实现自动驾驶——发布照片、点云、IMU、GPS、显示2D和3D侦测框

本次内容主要是使用kitti数据集来可视化kitti车上一些传感器&#xff08;相机、激光雷达、IMU&#xff09;采集的资料以及对行人和车辆进行检测并在图像中画出行人和车辆的2D框、在点云中画出行人和车辆的3D框。 首先先看看最终实现的效果&#xff1a; 自动驾驶视频 看了上面的…

KITTI数据集-label解析笔记

笔记摘自&#xff1a;KITTI数据集--label解析与传感器间坐标转换参数解析_苏源流的博客-CSDN博客 KITTI数据集是自动驾驶领域最知名的数据集之一。 一、kitti数据集&#xff0c;label解析 16个数代表的含义&#xff1a; 第1个字符串&#xff1a;代表目标的类别 Car, Van, Tru…

16个车辆信息检测数据集收集汇总(简介及链接)

16个车辆信息检测数据集收集汇总&#xff08;简介及链接) 转载自&#xff1a;https://blog.csdn.net/u014546828/article/details/109089621?utm_mediumdistribute.pc_relevant.none-task-blog-baidujs_baidulandingword-1&spm1001.2101.3001.4242 目录 1. UA-DETRAC …

双目网络公开数据集的特性

文章目录 概述SceneFlowKITTI 2012 & 2015ETH3D 2017Middlebury 2014 概述 参考文章&#xff1a;Rethinking Training Strategy in Stereo Matching 主流双目公开数据集有&#xff1a;SceneFlow、KITTI、ETH3D、MB。 各个双目网络主流训练数据视差分布的直方图&#xff1a;…

KITTI数据集下载及介绍

KITTI数据集下载及介绍 KITTI数据集由德国卡尔斯鲁厄理工学院和丰田美国技术研究院联合创办&#xff0c;是目前国际上最大的自动驾驶场景下的计算机视觉算法评测数据集。该数据集用于评测立体图像(stereo)&#xff0c;光流(optical flow)&#xff0c;视觉测距(visual odometry…

KITTI 数据集--下载链接

Visual Odometry / SLAM Evaluation 2012 数据集主页&#xff1a;The KITTI Vision Benchmark Suite (cvlibs.net) 里程计基准由22个立体序列组成&#xff0c;以无损失png格式保存。 11个具有真实轨迹的序列&#xff08;00-10&#xff09;用于训练&#xff0c;11个没有真实…