Java怎么用局域网实现聊天室功能
发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这篇文章主要介绍了Java怎么用局域网实现聊天室功能的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java怎么用局域网实现聊天室功能文章都会有所收获,下面我们一起来看看吧
千家信息网最后更新 2026年10月31日Java怎么用局域网实现聊天室功能
这篇文章主要介绍了Java怎么用局域网实现聊天室功能的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇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 clients=new CrazyitMap<>(); public void init(){ try( //建立监听的ServerSocket ServerSocket 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{ //创建一个线程安全的HashMap public Map map= Collections.synchronizedMap(new HashMap ()); //根据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 valueSet(){ Set result=new HashSet (); //将map中的所有value添加到result集合中 map.forEach((key,value)->result.add(value)); return result; } //根据value查找key public synchronized k getKeyByValue(v value){ //遍历所有key组成的集合 for (k key:map.keySet()){ //如果指定key对应的value与被搜索的value相同,则返回对应的key if(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没有收到:
关于"Java怎么用局域网实现聊天室功能"这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对"Java怎么用局域网实现聊天室功能"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。
输入
用户
服务器
服务
输出
信息
用户名
客户
字符
网络
字符串
客户端
线程
功能
局域
局域网
聊天室
不断
方法
登录
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
上海睿民互联网科技有限公司
科技制造互联网公司
深圳科技互联网
互联网 科技创业
互联网科技公司怎么样
互联网科技作文
善班互联网科技有限公司
融贸通互联网科技
互联网科技的未来发展
互联网科技汛
佳云科技和互联网广告
互联网科技与管理
互联网对科技的发展
互联网科技革命什么开始
晓花互联网科技有限公司网址
深圳互联网科技的发展
神州科技互联网有限公司
云南互联网科技学费
唐山双旺合互联网科技产业园
株洲百竞科技的互联网营销顾问
佰商互联网科技有限公司
丰台科技园 互联网公司
哈尔滨新华互联网科技学院
深圳市优智互联网科技有限公司
互联网科技的全部知识
工业互联网展湾科技股份有限公司
半导体是互联网高科技吗
艺电能源互联网科技有限公司招聘
北京瑞云互联网科技有限公司
银川新华互联网科技学校招聘