0

0

在Java里如何实现简易聊天室服务器_Java网络通信项目说明

P粉602998670

P粉602998670

发布时间:2026-01-19 08:23:20

|

151人浏览过

|

来源于php中文网

原创

ServerSocket可实现简易TCP聊天室:服务端用accept()阻塞监听,每客户端分配ClientHandler线程,广播消息需线程安全集合存储PrintWriter并及时移除断开连接;客户端需双线程收发,注意UTF-8编码与资源关闭。

在java里如何实现简易聊天室服务器_java网络通信项目说明

用 ServerSocket 实现基础 TCP 聊天室服务器

Java 原生 ServerSocket 就够用,不需要 Spring Boot 或 Netty——只要支持多客户端连接、广播消息,就能跑通简易聊天室。核心是“一个服务端线程监听连接,每个客户端分配一个独立线程处理读写”,适合学习网络模型,也足够应付几十人小规模测试。

注意:这不是生产级方案(无心跳、无断线重连、无消息序列化),但能清晰看到 SocketInputStreamOutputStream 如何协作。

  • 服务端启动后,调用 serverSocket.accept() 阻塞等待连接,每接受一个 Socket 就新建一个 ClientHandler 线程
  • 所有已连接的 Socket 输出流需存入线程安全集合(如 Collections.synchronizedList(new ArrayList())
  • 广播时遍历该集合,对每个 PrintWriter 调用 println()flush(),否则客户端收不到消息
  • 客户端断开时,必须从集合中移除对应 PrintWriter,否则后续广播会触发 IOException: Broken pipe
public class ChatServer {
    private static final List clients = Collections.synchronizedList(new ArrayList<>());
    
    public static void main(String[] args) throws IOException {
        try (ServerSocket serverSocket = new ServerSocket(8080)) {
            System.out.println("Chat server started on port 8080");
            while (true) {
                Socket clientSocket = serverSocket.accept();
                new ClientHandler(clientSocket).start();
            }
        }
    }

    static class ClientHandler extends Thread {
        private final Socket socket;
        private final BufferedReader in;
        private final PrintWriter out;

        ClientHandler(Socket socket) throws IOException {
            this.socket = socket;
            this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            this.out = new PrintWriter(socket.getOutputStream(), true);
        }

        public void run() {
            try {
                clients.add(out);
                String msg;
                while ((msg = in.readLine()) != null) {
                    System.out.println("Received: " + msg);
                    for (PrintWriter client : clients) {
                        client.println(msg); // 广播给所有人
                    }
                }
            } catch (IOException e) {
                // 客户端异常断开,清理资源
                clients.remove(out);
            } finally {
                try { socket.close(); } catch (IOException ignored) {}
            }
        }
    }
}

客户端用 Socket 连接并收发纯文本

简易聊天室客户端只需一个 Socket、一个 Scanner(读控制台)、一个 BufferedReader(收服务端消息)。关键在于两个线程:一个负责读用户输入并发送,另一个负责监听服务端推送——不能串行阻塞。

  • 发送线程用 System.in 读取 nextLine(),避免 nextInt() 后残留换行符导致下一次读取为空
  • 接收线程用 BufferedReader.readLine() 持续监听,遇到 null 表示服务端关闭连接
  • 客户端退出前必须调用 socket.close(),否则服务端无法感知断开,clients 列表持续膨胀
  • 不要在 main 线程里直接 readLine() 后再 println(),会导致“自己发的消息自己收不到”(因为没启接收线程)

常见错误:中文乱码和连接拒绝

乱码基本是字符集不一致:InputStreamReader 默认用平台编码(Windows 是 GBK),而现代 IDE 和终端多用 UTF-8。必须显式指定:

畅图
畅图

AI可视化工具

下载

立即学习Java免费学习笔记(深入)”;

  • 服务端构造 BufferedReader 时用 new InputStreamReader(socket.getInputStream(), "UTF-8")
  • 客户端同理,且 PrintWriter 构造需加 true 参数启用自动 flush,并指定编码:new OutputStreamWriter(socket.getOutputStream(), "UTF-8")
  • “Connection refused” 错误只说明服务端没在目标端口监听:检查 ServerSocket 是否已启动、端口是否被占用(netstat -an | grep 8080)、防火墙是否拦截
  • 启动顺序必须是先运行服务端,再启动多个客户端;反向操作必然报错

扩展性差在哪?别急着重构

这个实现撑不过 100 个并发连接——每个客户端占一个线程,线程创建/切换开销大,JVM 线程数也有上限(默认约 1024)。但对理解“连接管理”“消息分发”“资源清理”已经足够。

真正容易被忽略的是:没有区分发送者身份。当前所有消息都是“匿名广播”,如果要显示“[Alice]: hello”,就得在服务端为每个 ClientHandler 记录昵称(比如首条消息作为用户名),并在广播时拼接前缀——这需要修改 clients 存储结构,改用 Map,且首次注册时做重复校验。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

837

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

741

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

736

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

397

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

399

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16926

2023.08.03

PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

11

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.7万人学习

C# 教程
C# 教程

共94课时 | 7万人学习

Java 教程
Java 教程

共578课时 | 47.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号