Java基于Socket的局域网聊天室实现指南

Ryan
Ryan
发布时间:2026-10-15 | 4人浏览过
原创

本文介绍使用Java Socket构建局域网聊天室的完整流程,涵盖服务器端监听、客户端连接、多线程并发处理以及自定义消息协议(公聊/私聊)。通过CrazyitMap管理用户会话状态,实现简单的即时通讯功能。

系统架构与核心组件

该聊天室采用典型的 C/S(客户端/服务器)架构。服务端负责接收连接、维护在线用户映射表并转发消息;客户端负责用户交互、输入流读取与网络发送。系统主要包含以下六个核心文件:

  • Server.java:主服务类,启动ServerSocket监听端口。
  • ServerThread.java:服务端工作线程,处理单个客户端的IO循环及消息逻辑。
  • Client.java:主客户端类,建立TCP连接并启动输入输出线程。
  • ClientThread.java:客户端读线程,持续监听服务器推送的消息。
  • CrazyitMap.java:线程安全的HashMap封装,用于管理用户名与输出流的映射关系。
  • CrazyitProtocol.java:接口定义,规定消息包头的特殊标识字符,用于区分消息类型。

服务端实现

服务端是聊天室的核心,负责持久化监听 incoming connections 并进行业务路由。

第1步:启动服务监听

在Server.java中,初始化ServerSocket绑定特定端口(如30000),并通过死循环调用accept()阻塞等待客户端请求。每次接受到一个新Socket连接,便创建一个ServerThread实例并在后台启动。

public void init(){
    try( ServerSocket ss=new ServerSocket(SERVER_PORT)) {
        while(true){
            Socket socket=ss.accept();
            new ServerThread(socket).start();
        }
    }
    catch (IOException ex){
        System.out.println("服务器启动失败,是否端口"+SERVER_PORT+"已被占用");
    }
}

第2步:解析消息与分发逻辑

ServerThread进入run方法后,获取对应的输入输出流。循环读取字符串并根据首尾的特殊协议字符判断消息类型:

  1. 登录验证:识别USER_ROUND标识的内容为用户名。若该用户名已存在于Server.clients中,返回拒绝标识;否则允许登录并存入映射表。
  2. 私聊处理:识别PRIVATE_ROUND标识的内容。内部使用SPLIT_SIGN分割目标用户名和消息体,仅向目标用户的输出流写入数据。
  3. 公聊广播:若非上述两种情况,则视为普通消息。遍历所有在线用户的输出流进行广播发送。

当捕获到IOException时,意味着客户端非正常断开,服务端需从Map中移除该会话资源并关闭IO流。

客户端实现

客户端主要负责与服务器建立握手、格式化本地输入并展示远程消息。

第3步:建立连接与登录

客户端通过Socket("127.0.0.1", SERVER_PORT)发起连接。登录后进入循环,使用Swing JOptionPane提示用户输入名称。将用户名包装上协议头发送后,读取服务器反馈:LOGIN_SUCCESS表示成功,NAME_REP表示重名需重新输入。

第4步:并发读写分离

为保证界面不卡顿且能实时收发消息,采用双线程模型:

  • 写线程(主线程延伸)
    不断读取标准输入System.in。根据是否以//开头且包含冒号来区分私聊指令(格式://Username:Message),并按协议打包发送。
  • 读线程(ClientThread)
    启动独立线程持续读取服务器的BufferedReader,一旦有新消息立即打印至控制台。

协议设计与地图辅助类

第5步:配置通信协议

在CrazyitProtocol接口中定义了消息包的结构。例如私聊消息格式为:★【 目标用户 卐 内容 ★【。这种简单的方式便于服务器端通过字符串匹配快速路由。

第6步:维护用户映射

CrazyitMap是对HashMap的同步包装。它增加了两个关键方法:removeByValue用于根据连接对象查找并删除对应用户(应对客户端断连),getKeyByValue用于在服务器广播或私聊反向查询用户名。

运行效果演示

部署完成后,依次启动一个服务端程序和三个客户端程序,分别以xuwei、jiji和yaou作为昵称登录。

公聊测试

用户在命令行中输入公开文本。此时,所有已登录的客户端均应收到相同的广播信息。例如xuwei发送了一条公开信息,jiji和yaou的控制台均显示该内容。

xuwei发送了一句话:

jiji收到:

yaou收到:

私聊测试

在控制台中输入以//开头的指令进行测试,语法为//接收者:具体内容。
xuwei向jiji发送一条悄悄话:

此时只有目标用户jiji会看到带有前缀的提示消息,其他未指定的在线用户不会收到任何干扰。

jiji收到:

yaou没有受到干扰:

以上就是Java基于Socket实现局域网聊天室的详细内容,更多关于Java网络编程的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表