Java加强项目一:局域网聊天系统

woefulmoon 发布于 2025-04-25 Java


 

 

Java局域网聊天系统开发详解

项目概述

本项目实现了一个基于Java Swing和Socket编程的局域网聊天室系统,具备以下功能:

  • 用户通过昵称登录聊天室
  • 实时显示在线用户列表
  • 支持多用户同时聊天
  • 消息广播功能
  • 美观的聊天界面设计
[系统架构图]

系统架构

本系统采用C/S(客户端/服务器)架构,主要分为两部分:

组件 功能
客户端
  • LoginWindow.java:登录界面
  • ChatWindow.java:聊天主界面
  • ClientChatThread.java:消息接收线程
服务端
  • ChatServer.java:主服务器
  • SocketChatThread.java:客户端连接处理线程
通信协议:客户端和服务端通过自定义的简单协议进行通信,使用整数标识消息类型(1表示用户登录,2表示聊天消息)。

客户端实现详解

1. 登录界面 (LoginWindow.java)

登录界面采用Swing构建,包含昵称输入框和登录按钮:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public LoginWindow() {
    setTitle("聊天室登录");
    setSize(400, 250);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null); // 居中显示
   
    // 昵称输入框
    nicknameField = new JTextField(15);
    nicknameField.setFont(new Font("微软雅黑", Font.PLAIN, 14));
   
    // 登录按钮事件处理
    loginButton.addActionListener(e -> {
        String nickname = nicknameField.getText().trim();
        if (nickname.isEmpty()) {
            JOptionPane.showMessageDialog(this, "昵称不能为空!", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }
        // 建立连接并发送昵称
        socket = new Socket(Constant.SERVER_IP, Constant.SERVER_PORT);
        dos = new DataOutputStream(socket.getOutputStream());
        dos.writeInt(1); // 类型1表示登录消息
        dos.writeUTF(nickname);
        new ChatWindow(nickname, socket).setVisible(true);
        dispose(); // 关闭登录窗口
    });
}

2. 聊天主界面 (ChatWindow.java)

聊天主界面采用JSplitPane实现左右分栏布局:

  • 左侧:消息展示区
  • 右侧:在线用户列表
  • 底部:消息输入框和发送按钮
UI亮点:

  1. 支持多行消息显示
  2. 消息自动滚动到底部
  3. 鼠标悬停显示完整消息
  4. 美观的用户列表显示

3. 消息处理 (ClientChatThread.java)

独立的线程处理来自服务器的消息:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void run() {
    DataInputStream dis = new DataInputStream(is);
    int type;
    while (true) {
        type = dis.readInt();
        switch (type) {
            case 1: // 更新用户列表
                jf.updateUserList();
                break;
            case 2: // 新消息
                String msg = dis.readUTF();
                jf.addMsg(msg);
                break;
        }
    }
}

服务端实现详解

1. 主服务器 (ChatServer.java)

服务端使用多线程处理多个客户端连接:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class ChatServer {
    public static final Map<Socket, String> userMap = new HashMap<>();
   
    public static void main(String[] args) {
        try {
            ServerSocket ss = new ServerSocket(Constant.PORT);
            while (true) {
                Socket socket = ss.accept();
                new SocketChatThread(socket).start(); // 为每个连接创建线程
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2. 客户端线程处理 (SocketChatThread.java)

每个客户端连接由一个独立线程处理:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void run() {
    DataInputStream dis = new DataInputStream(socket.getInputStream());
    int type;
    while (true) {
        type = dis.readInt();
        switch (type) {
            case 1: // 新用户登录
                nickname = dis.readUTF();
                ChatServer.userMap.put(socket, nickname);
                toUpdataUserList(); // 更新所有用户的在线列表
                break;
            case 2: // 新消息
                String msg = dis.readUTF();
                toBroadcast(nickname, msg); // 广播消息给所有用户
                break;
        }
    }
}

3. 消息广播 (toBroadcast)

服务端实现消息广播功能:


1
2
3
4
5
6
7
8
9
10
11
private void toBroadcast(String nickname, String msg) {
    // 添加时间戳
    String resmsg = nickname + " " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
             + "\n" + msg;
    // 遍历所有在线用户发送消息
    for (Socket socket : ChatServer.userMap.keySet()) {
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        dos.writeInt(2); // 消息类型2
        dos.writeUTF(resmsg);
    }
}

核心技术分析

1. 线程安全处理

系统涉及多个线程操作共享的

1
userMap

,使用

1
synchronized

确保线程安全:


1
2
3
private synchronized void toUpdataUserList() throws Exception {
    // 用户列表更新操作
}

2. UI与网络线程分离

网络消息更新UI通过

1
SwingUtilities.invokeLater()

解决线程安全问题:


1
2
3
4
5
6
public void addMsg(String msg) {
    SwingUtilities.invokeLater(() -> {
        messageModel.addElement(msg);
        messageList.ensureIndexIsVisible(messageModel.getSize() - 1);
    });
}

3. 消息协议设计

使用简单的整数标识消息类型:

类型 描述
1 用户登录/用户列表更新
2 聊天消息

运行效果展示

1. 登录界面

登录界面截图

2. 聊天主界面

聊天界面截图

扩展思路

  • 添加私聊功能
  • 支持文件传输
  • 增加聊天表情支持
  • 添加消息历史记录
  • 增加数据库支持

总结

本局域网聊天系统实现了基本的即时通讯功能,涵盖了Swing UI设计、多线程编程、Socket通信等Java核心技术。

项目亮点:

  1. 简洁直观的用户界面
  2. 高效的消息处理机制
  3. 严谨的线程安全处理
  4. 良好的扩展性
学习收获:通过本项目,可以深入理解Java网络编程技术。