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
相关产品推荐
相关产品推荐

