简体   繁体   English

Java - 如何检查 ServerSocket.accept() 是否已连接?

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

I'm trying to write simple server-client chat solution.我正在尝试编写简单的服务器-客户端聊天解决方案。 For test purposes, I'm creating an array of 2 serverThreads, which are responsible for sending and receiving messages from the clients connected.出于测试目的,我创建了一个由 2 个 serverThreads 组成的数组,它们负责从连接的客户端发送和接收消息。

I'd like a server to reject a connections after the number of connected clients reach a maximum value.我希望服务器在连接的客户端数量达到最大值后拒绝连接。 However, even though the server do not accept the connection, the socket on client side is created.但是,即使服务器不接受连接,也会创建客户端的套接字。 Methods socket.isBound and isConnected both return true value. socket.isBound 和 isConnected 方法都返回真值。

So back to the main question.所以回到主要问题。 Do you have any ideas how could I reject the client from connecting when the ServerSocket will not be able to .accept() additional connection?当 ServerSocket 无法 .accept() 附加连接时,您有什么想法我怎么能拒绝客户端连接?

Here's the code of the Server class.这是 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();
 }

}

I'd like a server to reject a connections after the number of connected clients reach a maximum value.我希望服务器在连接的客户端数量达到最大值后拒绝连接。

Close the server socket.关闭服务器套接字。

However, even though the server do not accept the connection, the socket on client side is created.但是,即使服务器不接受连接,也会创建客户端的套接字。 Methods socket.isBound and isConnected both return true value. socket.isBoundisConnected方法都返回真值。

Correct.正确。 That's because TCP maintains a 'backlog queue' of incoming connections which have been completed but not yet accepted by the server application.这是因为 TCP 维护了一个“积压队列”,其中包含已完成但尚未被服务器应用程序接受的传入连接。

So back to the main question.所以回到主要问题。 Do you have any ideas how could I reject the client from connecting when the ServerSocket will not be able to .accept() additional connection?当 ServerSocket 无法 .accept() 附加连接时,您有什么想法我怎么能拒绝客户端连接?

Close the server socket while the number of connections is at its maximum.当连接数达到最大值时关闭服务器套接字。

However due to the backlog this technique can never be perfect.然而,由于积压,这种技术永远不会是完美的。 There is no perfect solution.没有完美的解决方案。 You could have the server immediately close excess connections, but the excess clients won't detect that until they try to send something.您可以让服务器立即关闭多余的连接,但多余的客户端在尝试发送某些内容之前不会检测到它。 If you need perfection you will probably have to introduce an application protocol whereby the server sends something like 'ACCEPTED' or 'REJECTED' accordingly.如果您需要完美,您可能必须引入一个应用程序协议,服务器相应地发送诸如“接受”或“拒绝”之类的内容。

Instead of while true in you waitForClient method try this而不是 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());
        }

} } } }

I know this is very late to answer, but I think it will help many.我知道现在回答已经很晚了,但我认为这会对很多人有所帮助。 You can check for the existing socket if any by below code.您可以通过以下代码检查现有套接字(如果有)。

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();
        }
    }

if not found a active socket on the same port and IP then it will start a new server socket or you can change it start socket only else you can connect to the existing socket.如果在同一端口和 IP 上没有找到活动套接字,那么它将启动一个新的服务器套接字,或者您可以更改它仅启动套接字,否则您可以连接到现有套接字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM