当前位置: 首页 > news >正文

Java网络编程实战(多人聊天室-CS模式)

一、C/S模式核心原理

1.1 基本架构

C/S(Client/Server)模式采用客户端-服务器架构:

  • 服务器端:持续运行,负责消息路由和广播
  • 客户端:用户交互界面,连接服务器进行通信
  • 通信协议:TCP(可靠连接)/UDP(无连接)

1.2 Java核心API

  • ServerSocket:服务器端监听端口
  • Socket:客户端建立连接
  • BufferedReader/PrintWriter:字符流操作

二、聊天室功能设计

2.1 功能需求

  • 多客户端连接
  • 实时消息广播
  • 用户昵称管理
  • 上下线通知

2.2 技术方案

模块技术实现
网络通信TCP Socket
并发处理多线程
消息协议自定义简单文本格式
用户管理线程安全集合

三、服务器端实现

3.1 服务器主类

public class ChatServer {
    private static final int PORT = 8888;
    private static Set<ClientHandler> clients = new HashSet<>();

    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("服务器启动,监听端口:" + PORT);
            
            while (true) {
                Socket clientSocket = serverSocket.accept();
                ClientHandler client = new ClientHandler(clientSocket);
                clients.add(client);
                new Thread(client).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 广播消息给所有客户端
    public static void broadcast(String message) {
        clients.removeIf(ClientHandler::isClosed);
        for (ClientHandler client : clients) {
            client.sendMessage(message);
        }
    }
}

3.2 客户端处理线程

class ClientHandler implements Runnable {
    private Socket socket;
    private PrintWriter out;
    private BufferedReader in;
    private String nickname;

    public ClientHandler(Socket socket) throws IOException {
        this.socket = socket;
        this.out = new PrintWriter(socket.getOutputStream(), true);
        this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        this.nickname = in.readLine(); // 读取昵称
        ChatServer.broadcast(nickname + " 进入了聊天室");
    }

    @Override
    public void run() {
        try {
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                ChatServer.broadcast(nickname + ": " + inputLine);
            }
        } catch (IOException e) {
            System.out.println(nickname + " 异常断开连接");
        } finally {
            closeConnection();
        }
    }

    // 关闭连接
    private void closeConnection() {
        try {
            ChatServer.broadcast(nickname + " 离开了聊天室");
            socket.close();
            in.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendMessage(String message) {
        out.println(message);
    }

    public boolean isClosed() {
        return socket.isClosed();
    }
}

四、客户端实现

4.1 客户端主类

public class ChatClient {
    private static final String SERVER_IP = "127.0.0.1";
    private static final int SERVER_PORT = 8888;

    public static void main(String[] args) {
        try {
            Socket socket = new Socket(SERVER_IP, SERVER_PORT);
            System.out.print("请输入昵称:");
            String nickname = new Scanner(System.in).nextLine();

            // 发送昵称
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            out.println(nickname);

            // 启动消息接收线程
            new Thread(new MessageReceiver(socket)).start();

            // 处理用户输入
            Scanner scanner = new Scanner(System.in);
            while (true) {
                String message = scanner.nextLine();
                out.println(message);
            }
        } catch (IOException e) {
            System.out.println("无法连接到服务器");
        }
    }
}

class MessageReceiver implements Runnable {
    private Socket socket;
    private BufferedReader in;

    public MessageReceiver(Socket socket) throws IOException {
        this.socket = socket;
        this.in = new BufferedReader(
            new InputStreamReader(socket.getInputStream()));
    }

    @Override
    public void run() {
        try {
            String response;
            while ((response = in.readLine()) != null) {
                System.out.println(response);
            }
        } catch (IOException e) {
            System.out.println("与服务器断开连接");
        }
    }
}

五、运行测试

5.1 启动服务器

$ java ChatServer
服务器启动,监听端口:8888

5.2 启动多个客户端

客户端1:

请输入昵称:Alice
欢迎进入聊天室!
Alice: 大家好!

客户端2:

请输入昵称:Bob
Alice 进入了聊天室
Bob: 你好!

相关文章:

  • ollama加载本地自定义模型
  • 在 Linux 系统(ubuntu/kylin)上安装 Docker
  • 玻璃厂退火炉“温度智囊”:Profinet转ModbusRTU网关
  • 目标检测YOLO实战应用案例100讲- 基于卷积神经网络的小目标检测算法研究与应用
  • 灵霄破茧:仙途启幕 - 灵霄门新篇-(4)
  • linux环境定时重启服务的流程分享
  • 关于FocalLoss 损失函数
  • 【C++算法】54.链表_合并 K 个升序链表
  • Ansible:role企业级实战
  • 4-6记录(B树)
  • 使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第七讲)
  • 【React】副作用 setState执行流程 内置钩子(Effect Callback Reducer)React.memo
  • 从 STP 到 RSTP 再到 MSTP:网络生成树协议的工作机制与发展
  • Docker部署.NetCore8项目
  • 【Axure视频教程】中继器表格轮播含暂停效果
  • 蓝桥杯真题:数字串个数
  • 【今日三题】小乐乐改数字 (模拟) / 十字爆破 (预处理+模拟) / 比那名居的桃子 (滑窗 / 前缀和)
  • Spring Security6 从源码慢速开始
  • 系统思考—提升解决动态性复杂问题能力
  • C++对象生命周期管理:从构造到析构的完整指南