簡體   English   中英

Java - 如何檢查 ServerSocket.accept() 是否已連接?

[英]Java - how can I check if the ServerSocket.accept()ed the connection?

我正在嘗試編寫簡單的服務器-客戶端聊天解決方案。 出於測試目的,我創建了一個由 2 個 serverThreads 組成的數組,它們負責從連接的客戶端發送和接收消息。

我希望服務器在連接的客戶端數量達到最大值后拒絕連接。 但是,即使服務器不接受連接,也會創建客戶端的套接字。 socket.isBound 和 isConnected 方法都返回真值。

所以回到主要問題。 當 ServerSocket 無法 .accept() 附加連接時,您有什么想法我怎么能拒絕客戶端連接?

這是 Server 類的代碼。

public class Server {

private ServerSocket serverSocket = null;
private ServerThread serverThread[] = new ServerThread[2];
protected volatile int clientCount = 0;

public Server (int port){
   try {
       System.out.println("Binding to port " + port + " ...");
       serverSocket = new ServerSocket (port);
       System.out.println("Binded to port " + port + ".");
   } catch (IOException e) {
       System.out.println("Failed binding to the port: " + e.getMessage());
        }
}

public void addThread (Socket socket){

   System.out.println ("Client connected at socket: " + socket);
   serverThread[clientCount] = new ServerThread (this, socket);
   try {
       serverThread[clientCount].open();
       serverThread[clientCount].start();
   } catch (IOException e) {e.getMessage();}

}

public void waitForClient () {

   boolean isLogPrinted = false;

   while (true){
       try {
           if (clientCount < serverThread.length){
               System.out.println ("Waiting for connection...");
               isLogPrinted = false;
               addThread (serverSocket.accept());
               clientCount++;
               System.out.println("Client count: " + clientCount);
           }
           else {
               if (!isLogPrinted){
                    System.out.println("MAXIMUM NUMBER OF CLIENTS REACHED! (" + clientCount + ").");
                    isLogPrinted = true;
               }
           }
       } catch (IOException e) {
           System.out.println("Error while waiting for new clients to connect: " + e.getMessage());
            }
   }
}

public synchronized void broadcastMessages (String msg){
   for (int i = 0; i < clientCount; i++)
       serverThread[i].sendMessage(msg);
}

public static void main (String args[]){
   Server server = new Server (4200);
   server.waitForClient();
 }

}

我希望服務器在連接的客戶端數量達到最大值后拒絕連接。

關閉服務器套接字。

但是,即使服務器不接受連接,也會創建客戶端的套接字。 socket.isBoundisConnected方法都返回真值。

正確。 這是因為 TCP 維護了一個“積壓隊列”,其中包含已完成但尚未被服務器應用程序接受的傳入連接。

所以回到主要問題。 當 ServerSocket 無法 .accept() 附加連接時,您有什么想法我怎么能拒絕客戶端連接?

當連接數達到最大值時關閉服務器套接字。

然而,由於積壓,這種技術永遠不會是完美的。 沒有完美的解決方案。 您可以讓服務器立即關閉多余的連接,但多余的客戶端在嘗試發送某些內容之前不會檢測到它。 如果您需要完美,您可能必須引入一個應用程序協議,服務器相應地發送諸如“接受”或“拒絕”之類的內容。

而不是 while true 在你的 waitForClient 方法中試試這個

private final int allowedClients = 10;
private int connectedClients = 0;
public void waitForClient () {

boolean isLogPrinted = false;

while (connectedClients <= allowedClients){
    try {
       if (clientCount < serverThread.length){
           System.out.println ("Waiting for connection...");
           isLogPrinted = false;
           addThread (serverSocket.accept());
           connectedClients++;
           System.out.println("Client count: " + clientCount);
       }
       else {
           if (!isLogPrinted){
                System.out.println("MAXIMUM NUMBER OF CLIENTS REACHED! (" + clientCount + ").");
                isLogPrinted = true;
           }
       }
   } catch (IOException e) {
       System.out.println("Error while waiting for new clients to connect: " + e.getMessage());
        }

} }

我知道現在回答已經很晚了,但我認為這會對很多人有所幫助。 您可以通過以下代碼檢查現有套接字(如果有)。

SocketAddress socketAddress = new InetSocketAddress("localhost", 8091);
    Socket socket = new Socket();
    ServerSocket serverSocket = null;
    try {
        socket.connect(socketAddress);
    } catch (IOException e) {
        e.printStackTrace();
    }
    if(socket == null) {
        try {
            serverSocket = new ServerSocket(8091);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

如果在同一端口和 IP 上沒有找到活動套接字,那么它將啟動一個新的服務器套接字,或者您可以更改它僅啟動套接字,否則您可以連接到現有套接字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM