chf
chf

Reputation: 13

Java ServerSocket only accepts 2 connections

Right now I am playing a little arround with Client-Server application for example to communicate via a java application with a raspberry pi which runs a server application.

Well by this I found a problem and I dont find a possible solution. Using the following code I can connect twice to server but after 2 connects it will not accept any more connections. For example I start the Client the first time, and it works everything nicely. Then I close the client and start it again and it works again. But if I close it and start it a 3rd time, it will do nothing. The server will not accept the connection. I tried it with different pcs in my private network but never got a 3rd connection running.

Here is the Code I am running on the server:

public class Receiver {

private final Logger logger = Logger.getLogger(this.getClass().getName());

private ServerSocket serverSocket;
private boolean isRunning;

public Receiver(int port) {
    isRunning = true;
    try {
        serverSocket = new ServerSocket(port);
        logger.log(Level.FINER, "start listening at port " + port);
        logger.log(Level.FINER, "established successful.");
    } catch (IOException e) {
        logger.log(Level.SEVERE, "Error while opening socket:\n" + LogUtil.getStackTrace(e));
        System.exit(1);
    }
}

/**
 * server starts to listen at the specific port
 */
public void listenServer() {
    logger.log(Level.FINER, "Server is listening");

    while (isRunning) {
        try {
            final Socket clientsocket = serverSocket.accept();
            logger.log(Level.FINER, "Server accepted Connection from " + clientsocket.getInetAddress());
            new Thread(new Runnable() {

                @Override
                public void run() {
                    handleConnection(clientsocket);
                }
            }).start();
        } catch (IOException e) {
            logger.log(Level.SEVERE, "Connection with Client failed.");
        }
    }
}

/**
 * handles the given connection
 * 
 * @param clientSocket
 *            the given client socket for this connection
 */
private void handleConnection(Socket clientSocket) {

    ObjectInputStream instream = null;
    ObjectOutputStream outstream = null;

    try {
        outstream = new ObjectOutputStream(clientSocket.getOutputStream());
        instream = new ObjectInputStream(clientSocket.getInputStream());
        final RequestProcessor processor = new RequestProcessor();
        final InetAddress inetAdress = clientSocket.getInetAddress();

        logger.log(Level.FINER, "handle connection from " + inetAdress);

        Object inob;
        while ((inob = instream.readObject()) != null) {
            logger.log(Level.FINER, "received Object from " + inetAdress);
            final ObjectOutputStream finalOutputStream = outstream;
            final Object finalInob = inob;

            new Thread() {
                public void run() {
                    setPriority(MAX_PRIORITY);
                    Object outob;
                    try {
                        outob = processor.processObject(finalInob);
                        logger.log(Level.FINER, "send Respond to: " + inetAdress + " Error: " + (outob instanceof ErrorMessage));
                        finalOutputStream.writeObject(outob);
                        finalOutputStream.flush();
                    } catch (IOException e) {
                        logger.log(Level.SEVERE, "Connection closed to " + inetAdress);
                    }
                }
            }.start();
        }

        closeConnection(clientSocket, instream, outstream);
    } catch (IOException e) {
        logger.log(Level.SEVERE, "Connection closed to " + clientSocket.getInetAddress());
    } catch (ClassNotFoundException e) {
        logger.log(Level.SEVERE, "Connection closed to " + clientSocket.getInetAddress());
    } finally {
        closeConnection(clientSocket, instream, outstream);
    }

}

/**
 * closes InputStream, OutputStream and socket
 * 
 * @param socket
 * @param instream
 * @param outstream
 */
private void closeConnection(Socket socket, InputStream instream, OutputStream outstream) {
    this.isRunning = false;
    if (instream != null) {
        try {
            instream.close();
        } catch (IOException e) {
        }
    }
    if (outstream != null) {
        try {
            outstream.close();
        } catch (IOException e) {
        }
    }
    if (socket != null) {
        try {
            socket.close();
        } catch (IOException e) {
        }
    }
    logger.log(Level.FINER, "Connection was closed to client " + socket.getInetAddress());
}

/**
 * closes all connections and ends the server
 */
public void endAllConnections() {
    this.isRunning = false;

    if (this.serverSocket != null)
        try {
            this.serverSocket.close();
        } catch (IOException e) {
            // do nothing
        }
      }
  }

and here is the client code which I am using to connect to this server:

public class SocketConnector implements IConnector {

    private final Logger logger = Logger.getLogger(this.getClass().getName());

    private Socket s;
    private ObjectOutputStream oos;
    private ObjectInputStream ois;

    /**
     * creates a new connection
     * 
     * @param host
     *            given host
     * @param port
     *            given port
     * 
     * @throws UnknownHostException
     * @throws IOException
     */
    public SocketConnector(String host, int port) throws UnknownHostException, IOException {
        logger.log(Level.FINER, "Establish connection to " + host + ":" + port);
        s = new Socket(host, port);
        oos = new ObjectOutputStream(s.getOutputStream());
        ois = new ObjectInputStream(s.getInputStream());
    }

        // some methos which use oos and ois.

Does someone maybe know why the server does not accept any more connections when 2 clients connected and disconnected from it? I googled alot arround but didn't find an adequate answer :/ The server log says it doesn't even accept the new connection.

Thanks in advance :)

Upvotes: 1

Views: 1735

Answers (1)

vutran
vutran

Reputation: 404

The situation is:
when calling final Socket clientsocket = serverSocket.accept(); the first time, it's waiting for the first client. when the first client connected, you pass this client to a thread then continue the loop that calls final Socket clientsocket = serverSocket.accept(); the second time. Since starting a thread take more time than going to the next loop, isRunning still is true. In handleConnection(Socket clientSocket), you call closeConnection(clientSocket, instream, outstream); which set isRunning to false. That is the point. When the second client connected, you also pass this client to another thread, then continue the loop where isRunning is false, so the loop is terminated. Hence, you can't get to the third client.

Upvotes: 2

Related Questions