JAVA实现聊天室(局域网)

article/2025/10/23 5:24:07

JAVA用局域网实现聊天室

  • 类和接口
    在这里插入图片描述
  • Server类(服务器端)
package Test;import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server {private static final int SERVER_PORT=30000;//使用CrazyitMap对象来保存每个客户名字和对应输出流之间的对应关系public static CrazyitMap<String,PrintStream> clients=new CrazyitMap<>();public void init(){try( //建立监听的ServerSocketServerSocket ss=new ServerSocket(SERVER_PORT)){//采用死循环来不断地接收来自客户端的请求while(true){Socket socket=ss.accept();new ServerThread(socket).start();}}//如果抛出异常catch (IOException ex){System.out.println("服务器启动失败,是否端口"+SERVER_PORT+"已被占用");}}public static void main(String[] args){Server server=new Server();server.init();}
}
  • ServerThread类
package Test;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;public class ServerThread extends Thread {private Socket socket;BufferedReader br = null;PrintStream ps = null;//定义一个构造器,用于接收一个Socket来创建ServerThread线程public ServerThread(Socket socket) {this.socket = socket;}public void run() {try {//获取该Socket对应的输入流br = new BufferedReader(new InputStreamReader(socket.getInputStream()));//获取该Socket对应的输出流ps = new PrintStream(socket.getOutputStream());String line = null;while ((line = br.readLine()) != null) {//如果读到的行以CrazyitProtocol.USER_ROUND开始,并以其结束//则可以确定读到的是用户登录的用户名if (line.startsWith(CrazyitProtocol.USER_ROUND) && line.endsWith(CrazyitProtocol.USER_ROUND)) {//得到真实消息String userName = getRealMsg(line);//如果用户名重复if (Server.clients.map.containsKey(userName)) {System.out.println("重复");ps.println(CrazyitProtocol.NAME_REP);} else {System.out.println("成功");ps.println(CrazyitProtocol.LOGIN_SUCCESS);Server.clients.put(userName, ps);}}//如果读到的行以CrazyitProtocol.PRIVATE_ROUND开始,//则可以确定是私聊信息,私聊信息只向特定的输入流发送else if (line.startsWith(CrazyitProtocol.PRIVATE_ROUND) && line.endsWith(CrazyitProtocol.PRIVATE_ROUND)) {//得到真实的消息String userAndMsg = getRealMsg(line);//以SPLIT_SIGN分割字符串,前半是私聊用户,后半是聊天信息String user = userAndMsg.split(CrazyitProtocol.SPLIT_SIGN)[0];String msg = userAndMsg.split(CrazyitProtocol.SPLIT_SIGN)[1];//获取私聊用户对应的输出流,并发送私聊信息Server.clients.map.get(user).println(Server.clients.getKeyByValue(ps) + "悄悄对你说:" + msg);}//公聊要向每一个Socket发送else {//得到真实消息String msg = getRealMsg(line);//遍历clients中的每个输出流for (PrintStream clientPs : Server.clients.valueSet()) {clientPs.println(Server.clients.getKeyByValue(ps) + "说:" + msg);}}}}//捕获到异常后,表明Socket对应的客户端已经出现了问题//所以程序将其对应的输出流从Map中删除catch (IOException e) {Server.clients.removeByValue(ps);System.out.println(Server.clients.map.size());//关闭网络,IO资源try {if (br != null) {br.close();}if (ps != null) {ps.close();}if (socket != null) {socket.close();}} catch (IOException ex) {ex.printStackTrace();}}}//将读到的内容去掉前后协议字符,恢复成真实数据private String getRealMsg(String line) {return line.substring(CrazyitProtocol.PROTOCOL_LEN,line.length()-CrazyitProtocol.PROTOCOL_LEN);}
}
  • Client类
package Test;import javax.swing.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;public class Client {private static final int SERVER_PORT=30000;private Socket socket;private PrintStream ps;private BufferedReader brServer;private BufferedReader keyIn;public void init(){try{//初始化代表键盘的输入流keyIn=new BufferedReader(new InputStreamReader(System.in));//连接到服务器端socket=new Socket("127.0.0.1",SERVER_PORT);//获取该Socket对应的输入流和输出流ps=new PrintStream(socket.getOutputStream());brServer=new BufferedReader(new InputStreamReader(socket.getInputStream()));String tip=" ";//采用不断循环地弹出对话框要求输入用户名while(true){String userName= JOptionPane.showInputDialog(tip+"输入用户名");//用户输入的用户名前后增加协议字符串后发送ps.println(CrazyitProtocol.USER_ROUND+userName+CrazyitProtocol.USER_ROUND);//读取服务器端的响应String result=brServer.readLine();//如果用户名重复,则开始下一次循环if (result.equals(CrazyitProtocol.NAME_REP)){tip="用户名重复,请重试";continue;}//服务器端登录成功if (result.equals(CrazyitProtocol.LOGIN_SUCCESS)){break;}}}//捕获到异常,关闭网络资源,并退出该程序catch (UnknownHostException ex){System.out.println("找不到远程服务器,请确定服务器已经启动");closeRs();System.exit(1);}catch(IOException ex){System.out.println("网络异常,请重新登录");closeRs();System.exit(1);}//以该Socket对应的输入流启动ClientThread线程new ClientThread(brServer).start();}//定义一个读取键盘输出,并以网络发送的方法private void readAndSend(){try{//不断读取键盘输入String line=null;while ((line=keyIn.readLine())!=null){//如果发送的信号中有冒号,并以//开头,则认为想发送私聊信息if (line.indexOf(":")>0&&line.startsWith("//")){line=line.substring(2);ps.println(CrazyitProtocol.PRIVATE_ROUND+line.split(":")[0]+CrazyitProtocol.SPLIT_SIGN+line.split(":")[1]+CrazyitProtocol.PRIVATE_ROUND);}else{ps.println(CrazyitProtocol.MSG_ROUND+line+CrazyitProtocol.MSG_ROUND);}}}catch (IOException ex){System.out.println("网络通信异常!请重新登录");closeRs();System.exit(1);}}//关闭Socket,输入流,输出流的方法private void closeRs(){try{if (keyIn!=null){ps.close();}if (brServer!=null){ps.close();}if (ps!=null){ps.close();}if (socket!=null){keyIn.close();}}catch (IOException ex){ex.printStackTrace();}}public static void main(String[] args){Client client=new Client();client.init();client.readAndSend();}
}
  • ClientThread类
package Test;import java.io.BufferedReader;
import java.io.IOException;public class ClientThread extends Thread {//该客户端线程负责处理输入流BufferedReader br=null;//使用一个网络输入流来创建客户端线程public ClientThread(BufferedReader br){this.br=br;}public void run(){try{String line=null;//不断地从输入流中读取数据,并将这些数据打印输出while((line=br.readLine())!=null){System.out.println(line);}}catch (IOException ex){ex.printStackTrace();}finally {try {if (br!=null){br.close();}}catch (IOException ex){ex.printStackTrace();}}}
}
  • CrazyitMap类
package Test;import java.util.*;public class CrazyitMap<k,v> {//创建一个线程安全的HashMappublic Map<k,v> map= Collections.synchronizedMap(new HashMap<k,v>());//根据value来删除指定项public synchronized void removeByValue(Object value){for (Object key:map.keySet()){if (map.get(key)==value){map.remove(key);break;}}}//获取所有value组成的Set集合public synchronized Set<v> valueSet(){Set<v> result=new HashSet<v>();//将map中的所有value添加到result集合中map.forEach((key,value)->result.add(value));return result;}//根据value查找keypublic synchronized k getKeyByValue(v value){//遍历所有key组成的集合for (k key:map.keySet()){//如果指定key对应的value与被搜索的value相同,则返回对应的keyif(map.get(key)==value||map.get(key).equals(value)){return key;}}return null;}//实现put()方法,该方法不允许value重复public synchronized v put(k key,v value){//遍历所有value组成的集合for (v val:valueSet()){//如果某个value与试图放入集合的value相同//则抛出一个RuntimeException异常if (val.equals(value)&&val.hashCode()==value.hashCode()){throw new RuntimeException("MyMap实例不允许有重复的value");}}return map.put(key,value);}
}
  • CrazyitProtocol类
package Test;public interface CrazyitProtocol {//定义协议字符串的长度int PROTOCOL_LEN=2;//下面是一些协议字符串,服务器端和客户端交换的信息都应该在前后添加这种特殊字符串String MSG_ROUND="ηθ";String USER_ROUND="∏∑";String LOGIN_SUCCESS="1";String NAME_REP="-1";String PRIVATE_ROUND="★【";String SPLIT_SIGN="卐";
}

运行结果:
打开服务器并且运行三个客户端用户名分别是xuwei,jiji和yaou
在这里插入图片描述
首先发送一句公开信息:
xuwei发送了一句话
在这里插入图片描述
jiji收到:
在这里插入图片描述
yaou收到:
在这里插入图片描述
再发送一句私聊信息给jiji
xuwei发送了一句悄悄话:
在这里插入图片描述
jiji收到:
在这里插入图片描述
yaou没有收到:
在这里插入图片描述


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

相关文章

Java在线聊天室课程设计(嘉然UI界面)

文章目录 一、前言 &#x1f606;二、效果展示图 &#x1f9d0;1、服务器界面2、客户端登录界面3、聊天界面 三、客户端Client &#x1f642;1、LoginFrame类2、ClientHandler类3、ChatFrame类 四、服务器端Server &#x1f643;1、ServerFrame类2、ServerInfoPanel类3、Online…

java聊天室源代码(练习项目)

聊天室界面如下&#xff1a; 聊天室源代码链接 一、服务端&#xff1a; 窗体&#xff1a; package sonyi.server;import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import jav…

Java—简易聊天室

Java—聊天室的实现 在学习了IO流&#xff0c;多线程以及网络编程的知识之后&#xff0c;我们可以利用所学到的知识做一个小项目&#xff0c;这里我做了一个多人聊天室&#xff0c;实现了群聊和私聊功能&#xff0c;看完分享之后也可以自己去做一个练练手。 首先是整个项目的…

java聊天室(实训项目)

这里是我们实训的一个关于java聊天室的项目&#xff0c;有需要的同学可以看看&#xff0c;私聊功能未完善。 话不多说&#xff0c;直接上代码。 服务器&#xff1a; package ChatRoom;import java.awt.Color; import java.awt.Component; import java.awt.EventQueue; impor…

Java实现简易聊天室

Java实现简易聊天室 在学习《Java从入门到精通》这本书&#xff0c;网络通信&#xff0c;基于TCP实现的简易聊天室&#xff0c;我这里对书中的代码略做了修改&#xff0c;做个记录。 这里先放一下运行效果图&#xff0c;代码放在最后。 运行效果&#xff1a; 先启动服务器端&am…

javaWeb实现聊天室(私聊+群聊)

写在前面 近几天&#xff0c;迎来了第一个小项目&#xff0c;不做不知道&#xff0c;一做吓一跳。好多知识都掌握的不够扎实&#xff0c;看似会了&#xff0c;但其实似懂非懂&#xff0c;不能真正掌握原理&#xff0c;导致使用起来错误百出。而且深深体会到&#xff0c;知识只有…

java实现聊天室(GUI界面+私聊+群聊)

登录界面的用户名和端口号不能重复&#xff01; 登录界面的用户名和端口号不能重复&#xff01; 登录界面的用户名和端口号不能重复&#xff01; java的socket编写的聊天室&#xff0c;GUI的界面&#xff0c;可以私聊和群聊&#xff0c; 聊天信息保存为txt 有需要的可以自行下…

用Java代码实现一个简单的聊天室功能

一.客户端的创建 1.我们可以用Socket来创建客户端 /***类名 Client*描述 TODO 客户端 1*版本 1.0*创建人 XuKang*创建时间 2020/9/24 16:18**/ public class Client {public static void main(String[] args) throws UnknownHostException, IOException {System.out.println(…

Java在线聊天室(客户端+服务器)

Java在线聊天室&#xff08;客户端服务器&#xff09;基于webSocket实现模拟在线聊天系统 运行环境&#xff1a; JDK1.8version 开发环境&#xff1a;Eclipse 一、结构 以下是系统主要结构&#xff1a; 1.用户&#xff08;均实现部分可能会有bug&#xff09; &#xff08;…

apiDay09整理笔记(笔记优化)

目录 1.聊天室&#xff08;续&#xff09; &#xff08;1&#xff09;实现服务端发送消息给客户端 &#xff08;2&#xff09;服务端转发消息给所有客户端 &#xff08;3&#xff09;客户端解决收发消息的冲突问题 &#xff08;4&#xff09;服务端完成处理客户端断开连接…

JAVA简单聊天室的实现

目录 界面效果图 一、聊天室功能介绍&#xff1f; 二、功能代码 1.服务端 2.客户端 界面效果图 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、聊天室功能介绍&#xff1f; 1. 、对于聊天室就是处理多个客户端发送的请求与信息&#xff0c;从…

Java网络聊天室---个人博客

Java网络聊天室 ———个人博客 一、项目简介 功能描述&#xff1a; 使用图形用户界面和socket通信&#xff0c;能实现一个聊天室中多人聊天&#xff0c;可以两人私聊&#xff0c;可以发送文件。 实现类似QQ用户注册、登录、聊天等功能。 参考git地址或博客地址&#xff1a…

Java实现ChatRoom

基于连接通信Socket、多线程的Java聊天室 1、开发环境&#xff1a; IDEA2018.1JDK1.8 2、实现功能&#xff1a; 实现了模拟登录注册、群聊、私聊、显示当前在线人数列表&#xff1b; 在发送信息时&#xff0c;会向对方发送者及显示发送时间&#xff1b; 显示在线人数列表…

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;持续更新中 实现效果 实现思路 其实有半数代码是创建数据库和创建数据表并插入数据这些环境配置部分我都写好了&…