You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java多线程TCP Socket如何统计在线用户数并更新FrmServer界面标签

实现方案

核心逻辑是在用户登录/断开的节点触发FrmServer的标签更新,同时注意Swing控件必须在事件调度线程(EDT)中修改,避免界面卡死或异常。

步骤1:修改FrmServer类新增人数更新方法

给你的FrmServer窗体类新增一个公开的更新方法,确保标签修改逻辑跑在Swing EDT线程中:

public class FrmServer extends JFrame {
    // 你原来的在线人数标签,假设变量名是lblOnlineCount
    private JLabel lblOnlineCount;

    // 新增的更新在线人数方法
    public void updateOnlineCount(int count) {
        SwingUtilities.invokeLater(() -> {
            lblOnlineCount.setText("当前在线用户:" + count);
        });
    }

    // 你原有类的其他逻辑...
}

步骤2:把FrmServer实例改成全局可访问

你原来的frmServer是main方法里的局部变量,EchoThread拿不到引用,把它改成主类的静态成员,同时把非线程安全的ArrayList替换为并发容器避免多线程操作异常:

// 你的服务端主类,比如类名叫GameServer
public class GameServer {
    // 新增静态FrmServer实例
    public static FrmServer frmServer;
    // 替换为线程安全的并发列表
    public static CopyOnWriteArrayList<EchoThread> clients = new CopyOnWriteArrayList<>();
    public static final int PORT = 你自定义的端口号;

    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        // 实例化赋值给静态变量
        frmServer = new FrmServer();
        frmServer.setVisible(true);
        try {
            serverSocket = new ServerSocket(PORT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        while (true) {
            try {
                socket = serverSocket.accept();
            } catch (IOException e) {
                System.out.println("I/O error: " + e);
            }
            EchoThread echoThread = new EchoThread(socket);
            echoThread.start();
        }
    }
}

步骤3:在EchoThread的登录/断开节点触发更新

你已经写完了登录和断开逻辑,只需要在对应位置加触发代码即可:

public class EchoThread extends Thread {
    private Socket socket;
    // 标记用户是否已经登录成功,避免未登录的连接断开时误改计数
    private boolean isLogin = false;

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

    @Override
    public void run() {
        // 你原来的连接处理逻辑...

        // 【登录成功的逻辑节点】
        if (登录校验通过) {
            isLogin = true;
            GameServer.clients.add(this);
            // 触发窗体更新
            GameServer.frmServer.updateOnlineCount(GameServer.clients.size());
        }

        // 你原来的业务处理逻辑...

        // 【用户断开连接的逻辑节点】,正常退出、异常报错都走这个分支
        finally {
            if (isLogin) {
                GameServer.clients.remove(this);
                GameServer.frmServer.updateOnlineCount(GameServer.clients.size());
            }
            // 你原来的关闭socket、IO流的逻辑...
        }
    }
}

内容的提问来源于stack exchange,提问作者tedd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 14:15:03