Java 网络编程小试 结合 MySQL 开发「多用户在线聊天室」

技术栈与准备

开发多用户在线聊天室需要结合Java Socket编程和MySQL数据库。Java负责网络通信,MySQL用于存储用户信息和聊天记录。确保已安装JDK、MySQL及对应JDBC驱动。

数据库设计

创建数据库chatroom,设计两张核心表:

  1. users表:存储用户信息
    CREATE TABLE users (
        id INT AUTO_INCREMENT PRIMARY KEY,
        username VARCHAR(50) UNIQUE NOT NULL,
        password VARCHAR(50) NOT NULL,
        online_status BOOLEAN DEFAULT false
    );
    

  2. messages表:存储聊天记录
    CREATE TABLE messages (
        id INT AUTO_INCREMENT PRIMARY KEY,
        sender_id INT NOT NULL,
        content TEXT NOT NULL,
        send_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (sender_id) REFERENCES users(id)
    );
    

服务端实现

使用Java ServerSocket处理多客户端连接,每个客户端通过独立线程处理。

public class ChatServer {
    private static final int PORT = 8888;
    private static Set<ClientHandler> clients = new HashSet<>();
    private static ExecutorService pool = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(PORT);
        System.out.println("Server started on port " + PORT);
        
        while (true) {
            Socket clientSocket = serverSocket.accept();
            ClientHandler clientThread = new ClientHandler(clientSocket);
            clients.add(clientThread);
            pool.execute(clientThread);
        }
    }
}

客户端处理器

每个客户端连接后,独立线程处理消息收发和数据库交互。

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

    public ClientHandler(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream(), true);
            
            // 用户认证逻辑
            username = authenticateUser();
            broadcast(username + " joined the chat");
            
            // 消息处理循环
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                if (inputLine.equals("/exit")) break;
                saveMessageToDB(inputLine);
                broadcast(username + ": " + inputLine);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 清理资源
        }
    }
}

数据库交互

通过JDBC实现用户验证和消息存储。

private String authenticateUser() throws IOException {
    out.println("Enter username:");
    String username = in.readLine();
    out.println("Enter password:");
    String password = in.readLine();

    try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS)) {
        String sql = "SELECT * FROM users WHERE username=? AND password=?";
        PreparedStatement stmt = conn.prepareStatement(sql);
        stmt.setString(1, username);
        stmt.setString(2, password);
        ResultSet rs = stmt.executeQuery();
        
        if (!rs.next()) {
            out.println("Invalid credentials");
            return authenticateUser(); // 递归重试
        }
        
        // 更新在线状态
        sql = "UPDATE users SET online_status=true WHERE username=?";
        stmt = conn.prepareStatement(sql);
        stmt.setString(1, username);
        stmt.executeUpdate();
    }
    return username;
}

消息广播功能

向所有连接的客户端发送消息。

private void broadcast(String message) {
    for (ClientHandler client : ChatServer.clients) {
        if (client != this) {
            client.out.println(message);
        }
    }
}

客户端实现

客户端通过Socket连接到服务器,并开启两个线程分别处理消息发送和接收。

public class ChatClient {
    public static void main(String[] args) {
        try (Socket socket = new Socket("localhost", 8888);
             BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
             PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
             Scanner scanner = new Scanner(System.in)) {
            
            // 接收服务器消息的线程
            new Thread(() -> {
                while (true) {
                    String response = in.readLine();
                    if (response == null) break;
                    System.out.println(response);
                }
            }).start();
            
            // 用户输入处理
            while (scanner.hasNextLine()) {
                String input = scanner.nextLine();
                out.println(input);
                if (input.equals("/exit")) break;
            }
        }
    }
}

功能扩展建议

  1. 用户注册:增加用户注册功能,将新用户插入数据库
  2. 历史消息:连接时加载最近的聊天记录
  3. 私聊功能:支持@username格式的私聊消息
  4. 心跳检测:定时检测客户端连接状态,自动清理断连用户

注意事项

  1. 使用线程池管理客户端连接,避免资源耗尽
  2. 数据库操作需要处理SQL异常和连接关闭
  3. 消息广播时需同步处理clients集合,避免并发修改异常
  4. 生产环境应使用加密通信和密码哈希存储
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值