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

服务器并发客户端连接数限制及队列接入实现需求

Implement Client Connection Limit with Waiting Queue

Got it, let's break down how to add the connection limit (max 5 concurrent clients) and waiting queue functionality to your existing server code. Here's the step-by-step implementation:

1. Add Required Member Variables

First, add these fields to your server class to track the max connections and hold waiting clients:

// Maximum number of concurrent clients allowed
private static final int MAX_CONCURRENT_CLIENTS = 5;
// Queue to hold clients waiting for a connection slot
private final Queue<Socket> waitingClientQueue = new LinkedList<>();

2. Modify the start() Method to Handle Queueing

Update the connection acceptance logic to check if we've hit the client limit. If yes, add the new client to the queue; otherwise, spin up a ClientThread immediately:

public void start() {
    keepGoing = true;
    /* 创建Socket服务器并等待连接请求 */
    try {
        // 服务器使用的Socket
        ServerSocket serverSocket = new ServerSocket(port);
        // 循环等待连接
        while(keepGoing) {
            // 输出等待提示信息
            display("Server waiting for Clients on port " + port + ".");
            Socket socket = serverSocket.accept(); // 接受连接
            // 若收到停止指令则退出
            if(!keepGoing) {
                socket.close(); // Close the new socket to avoid client hanging
                break;
            }

            synchronized(this) {
                if(al.size() < MAX_CONCURRENT_CLIENTS) {
                    // Slot available: create and start client thread
                    ClientThread t = new ClientThread(socket);
                    al.add(t);
                    t.start();
                    display("New client connected. Current active clients: " + al.size());
                } else {
                    // No slots left: add to waiting queue
                    waitingClientQueue.add(socket);
                    display("Client added to waiting queue. Queue size: " + waitingClientQueue.size());
                    
                    // Optional: Notify client they're in queue
                    try (PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
                        out.println("Server is full. You're in queue. Position: " + waitingClientQueue.size());
                    } catch(IOException e) {
                        display("Failed to send queue status to client: " + e);
                        socket.close();
                        waitingClientQueue.remove(socket);
                    }
                }
            }
        }
        // 执行停止操作
        try {
            serverSocket.close();
            
            // Close all waiting client sockets
            while(!waitingClientQueue.isEmpty()) {
                Socket waitingSocket = waitingClientQueue.poll();
                try {
                    waitingSocket.close();
                } catch(IOException e) {
                    display("Error closing waiting client socket: " + e);
                }
            }
            
            for(int i = 0; i < al.size(); ++i) {
                ClientThread tc = al.get(i);
                try {
                    tc.sInput.close();
                    tc.sOutput.close();
                    tc.socket.close();
                } catch(IOException ioE) {
                    // 无有效处理措施
                }
            }
        } catch(Exception e) {
            display("Exception closing the server and clients: " + e);
        }
    } 
    // 捕获异常
    catch (IOException e) {
        String msg = sdf.format(new Date()) + " Exception on new ServerSocket: " + e + "\n";
        display(msg);
    }
}

3. Update the remove() Method to Process Waiting Clients

When a client disconnects, check the waiting queue and let the next client in:

// 处理客户端通过LOGOUT消息发起的注销
synchronized void remove(int id) {
    // 遍历ArrayList查找对应ID的客户端
    for(int i = 0; i < al.size(); ++i) {
        ClientThread ct = al.get(i);
        // 找到目标客户端
        if(ct.id == id) {
            al.remove(i);
            display("Disconnected Client " + ct.username + " removed from list. Current active clients: " + al.size());
            
            // Check if there are waiting clients to connect
            if(!waitingClientQueue.isEmpty()) {
                Socket nextClientSocket = waitingClientQueue.poll();
                ClientThread newClientThread = new ClientThread(nextClientSocket);
                al.add(newClientThread);
                newClientThread.start();
                
                // Optional: Notify client they're now connected
                try (PrintWriter out = new PrintWriter(nextClientSocket.getOutputStream(), true)) {
                    out.println("You're now connected to the server!");
                } catch(IOException e) {
                    display("Failed to send connection success message: " + e);
                    al.remove(newClientThread);
                    nextClientSocket.close();
                }
                
                display("Client from queue connected. Current active clients: " + al.size() + ", Queue size: " + waitingClientQueue.size());
            }
            return;
        }
    }
}

Key Notes & Recommendations

  • Thread Safety: We use synchronized(this) to ensure safe access to the active clients list (al) and waiting queue, since multiple threads (main accept thread, client threads calling remove) will modify these structures. Alternatively, you could use a ConcurrentLinkedQueue for the waiting clients to reduce lock contention.
  • Client Timeouts: Waiting clients might disconnect unexpectedly. You could add logic to periodically check for closed sockets in the queue and remove them, or set a timeout on the waiting sockets.
  • User Feedback: The optional queue status messages help users understand why their connection is delayed, which improves the overall experience.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:21:15