news 2026/8/1 14:08:50

从群聊到私聊:一个Java聊天室的推进

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从群聊到私聊:一个Java聊天室的推进

通信协议对比

1.0:

  • 客户端直接发送:“你好”
  • 服务端转发:xx:“你好”

2.0:

  • 群聊:
    • 客户端发送内容:“你好”
    • 协议格式:2#你好
  • 私聊:
    • 客户端发送内容:“@小蒲 你好”
    • 协议格式:1#小蒲#你好

通信协议设计

客户端——>服务端协议(发送)

public void send(String message) { //消息类型 好友名称长度 好友名称 信息类型 消息长度 消息内容 //通过@区分是不是私聊 char c1 = message.charAt(0); //获取消息的第一个字符 判断是不是@ try { OutputStream os = socket.getOutputStream(); //输出流 DataOutputStream dos = new DataOutputStream(os); if (c1 == '@') { int index = message.indexOf(' '); //索引字符位置 String fid = message.substring(1, index); //@和“ ”之间就是好友名称 substring 截取 String msg = message.substring(index + 1)+"(来自的"+account+"私聊消息)"; //获取发送者昵称 System.out.println(fid + " " + msg); dos.writeInt(1); //私聊 //发送好友名称及消息 依旧长度+内容 int fidLen = fid.getBytes().length; dos.writeInt(fidLen); dos.write(fid.getBytes()); int msgLen = msg.getBytes().length; dos.writeInt(msgLen); dos.write(msg.getBytes()); } else { dos.writeInt(2);//群聊 byte[] msgs = message.getBytes("UTF-8"); int len = msgs.length; dos.writeInt(len); dos.write(msgs); } dos.flush(); } catch (IOException e) { throw new RuntimeException(e); } }
  • 用@作为私聊标识
  • 用1和2区分私聊/群聊
  • 用writeInt发送可变长度数据

服务端——>客户端协议(读取&&转发)

public String receive(InputStream is,Socket socket){ DataInputStream dis=new DataInputStream(is); try { //读取消息类型 私聊1 群聊2 int type=dis.readInt(); if(type==1){ int fidLen=dis.readInt(); byte[] fid=new byte[fidLen]; dis.readFully(fid); String fidStr=new String(fid); int msgLen=dis.readInt(); byte[] msgs=new byte[msgLen]; dis.readFully(msgs); String msg=new String(msgs); System.out.println("收到一条发给"+fidStr +"的私聊消息:"+msg); return "1"+"#"+fidStr+"#"+msg; }else{ int len=dis.readInt(); byte[] msgs=new byte[len]; dis.readFully(msgs); String msg=new String(msgs,"UTF-8"); for (int i = 0; i < socketList.size(); i++) { ClientUser clientUser=socketList.get(i); Socket socket2=clientUser.socket; if (socket2==socket){ System.out.println(clientUser.account+":"+msg); } } return "2"+"#"+msg; } } catch (IOException e) { throw new RuntimeException(e); } }

服务端收到后,统一用#分隔符封装,转发

  • 私聊返回格式
    • return "1"+"#"+fidStr+"#"+msg;
  • 群聊返回格式
    • return "2"+"#"+msg;

服务端proClientMsg解析时:

public void proClientMsg(Socket socket){ new Thread(()->{ //登录 //读取用户名 String account= proLogin(socket); ClientUser clientUser=new ClientUser(account, socket); //保存clientUser 对象 包含一个socket和一个用户名 socketList.add(clientUser); while (true){ try { InputStream is=clientUser.socket.getInputStream(); String msg=receive(is,clientUser.socket); String[] datas=msg.split("#");//通过#将消息拆分成多个片段 变成数组数据 String type=datas[0]; if(type.equals("1")){ String fid=datas[1]; String msg1=datas[2]; for (int i = 0; i < socketList.size(); i++) { ClientUser otherCu = socketList.get(i); if (otherCu.account.equals(fid)){ send(clientUser.account+":"+msg1,otherCu.socket.getOutputStream()); break; } } }else{ String msg1=datas[1]; for (int i = 0; i < socketList.size(); i++) { ClientUser otherCu=socketList.get(i); Socket socket1=otherCu.socket; if (socket1!=clientUser.socket){ send(clientUser.account+":"+msg1,socket1.getOutputStream()); } } } } catch (IOException e) { throw new RuntimeException(e); } } }).start(); }


PS:indexOf('a') //索引字符a位置

substring(1,4) //截取字符串中从第二个字符到第五个字符之间的内容

split("#") //通过#将消息拆分成多个片段

String[] datas=msg.split("#"); //将拆分的消息变成数组数据

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/1 14:07:52

Qt QStringListModel与QListView:MVC架构实现字符串列表管理

在 Qt C 项目中&#xff0c;当需要展示和管理一组字符串列表时&#xff0c;直接使用 QListWidget 虽然简单&#xff0c;但缺乏数据与视图分离的灵活性。 QStringListModel 和 QListView 的组合正是为此场景设计的标准 MVC&#xff08;Model-View-Controller&#xff09;模…

作者头像 李华
网站建设 2026/8/1 14:06:38

GrapesJS:无需代码的可视化网页构建框架

GrapesJS&#xff1a;无需代码的可视化网页构建框架 【免费下载链接】grapesjs Free and Open source Web Builder Framework. Next generation tool for building templates without coding 项目地址: https://gitcode.com/GitHub_Trending/gr/grapesjs GrapesJS是一款…

作者头像 李华
网站建设 2026/8/1 14:02:48

MD Video:3分钟学会用Markdown轻松制作专业视频

MD Video&#xff1a;3分钟学会用Markdown轻松制作专业视频 【免费下载链接】mdvideo Markdown To Video, 一个将markdown文档转为视频的便捷工具 项目地址: https://gitcode.com/gh_mirrors/md/mdvideo 你是否曾经为了制作一个简单的演示视频而耗费数小时&#xff0c;在…

作者头像 李华
网站建设 2026/8/1 14:02:37

MQL5零基础入门:用ChatGPT帮你写第一个黄金EA(附完整代码)

最近帮很多朋友做EA测评&#xff0c;发现很多人想学EA编程但卡在第一步——不会英文、看不懂代码。 今天这篇就是给零基础的人写的。我会把每一行代码的意思都翻译成中文&#xff0c;看完你就能写出自己的第一个EA。 第一步&#xff1a;打开MT5的代码编辑器 打开你的MT5 → 左…

作者头像 李华
网站建设 2026/8/1 13:59:29

Chaos Blade终极实战指南:5分钟掌握云原生混沌工程注入技术

Chaos Blade终极实战指南&#xff1a;5分钟掌握云原生混沌工程注入技术 【免费下载链接】chaosblade An easy to use and powerful chaos engineering experiment toolkit.&#xff08;阿里巴巴开源的一款简单易用、功能强大的混沌实验注入工具&#xff09; 项目地址: https:…

作者头像 李华
网站建设 2026/8/1 13:59:05

基于STM32与PID算法的智能巡线小车全流程开发指南

1. 项目概述&#xff1a;从零打造一台会“思考”的巡线小车几年前&#xff0c;我第一次接触智能小车项目时&#xff0c;被它那种“简单硬件组合出复杂行为”的魅力深深吸引。一台能自主沿着黑线行走的小车&#xff0c;看似是电子爱好者入门的经典课题&#xff0c;实则是一个微缩…

作者头像 李华