繁体   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