Java ServerSocket只接受2个连接

时间:2014-01-15 19:30:47

标签: java sockets

现在我正在使用Client-Server应用程序进行一些工作,例如通过带有运行服务器应用程序的raspberry pi的Java应用程序进行通信。

通过这个我发现了一个问题,我找不到可能的解决方案。使用以下代码我可以连接两次到服务器但在2次连接后它将不再接受任何连接。例如,我第一次启动客户端,它很好地工作。然后我关闭客户端并再次启动它再次工作。但如果我关闭它并第三次启动它,它将什么也不做。服务器不接受连接。我在我的私人网络中尝试使用不同的PC,但从未运行第三个连接。

以下是我在服务器上运行的代码:

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
        }
      }
  }

这是我用来连接这个服务器的客户端代码:

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.

当有2个客户端连接并断开连接时,有人可能知道为什么服务器不再接受任何连接?我google了很多但没有找到合适的答案:/ 服务器日志表示它甚至不接受新连接。

提前致谢:)

1 个答案:

答案 0 :(得分:2)

情况是:
第一次调用final Socket clientsocket = serverSocket.accept();时,它正在等待第一个客户端。当第一个客户端连接时,将此客户端传递给线程,然后继续第二次调用final Socket clientsocket = serverSocket.accept();的循环。由于启动线程比进入下一个循环花费的时间更长,isRunning仍然是true。在handleConnection(Socket clientSocket),您致电closeConnection(clientSocket, instream, outstream);,将isRunning设置为false。这就是重点。当第二个客户端连接时,您还将此客户端传递给另一个线程,然后继续isRunningfalse的循环,以便终止循环。因此,你无法到达第三个客户。