当ServerSocket抛出IOException并保持服务器运行时该怎么办

s58*_*804 5 java sockets networking

基本上我想创建一个坚如磐石的服务器.

while (keepRunning.get()) {
    try {
        Socket clientSocket = serverSocket.accept();

        ... spawn a new thread to handle the client ...
    } catch (IOException e) {
        e.printStackTrace();
        // NOW WHAT?
    }
}
Run Code Online (Sandbox Code Playgroud)

在IOException块中,该怎么办?Server套接字是否有故障,因此需要重新创建?例如,等待几秒钟然后

serverSocket = ServerSocketFactory.getDefault().createServerSocket(MY_PORT);
Run Code Online (Sandbox Code Playgroud)

但是,如果服务器套接字仍然正常,那么关闭它并终止仍在通信的所有先前接受的连接是很可惜的.

编辑:经过一些回答,这里我尝试处理IOException.实现是否可以保证服务器保持正常运行,只在必要时才重新创建服务器套接字?

while (keepRunning.get()) {
    try {
        Socket clientSocket = serverSocket.accept();

        ... spawn a new thread to handle the client ...
        bindExceptionCounter = 0;
    } catch (IOException e) {
        e.printStackTrace();

        recreateServerSocket();
    }
}

private void recreateServerSocket() {
    while (keepRunning) {
        try {
            logger.info("Try to re-create Server Socket");
            ServerSocket socket = ServerSocketFactory.getDefault().createServerSocket(RateTableServer.RATE_EVENT_SERVER_PORT);

            // No exception thrown, then use the new socket.
            serverSocket = socket;
            break;
        } catch (BindException e) {
            logger.info("BindException indicates that the server socket is still good.", e);
            bindExceptionCounter++;

            if (bindExceptionCounter < 5) {
                break;
            }
        } catch (IOException e) {
            logger.warn("Problem to re-create Server Socket", e);
            e.printStackTrace();

            try {
                Thread.sleep(30000);
            } catch (InterruptedException ie) {
                logger.warn(ie);
            }
        }
    }
}    
Run Code Online (Sandbox Code Playgroud)

mdm*_*dma 4

如果有疑问,您可以尝试使用相同的端口重新创建服务器套接字。如果套接字已关闭,则创建将成功,您可以继续处理新连接。旧的连接已经消失,但由于套接字已关闭,因此这超出了您的控制范围。如果套接字未关闭,则创建新实例将失败,因为该端口仍在使用中,您可以忽略它 - 即不要替换当前服务器套接字引用。

一般来说,客户端还应该假设连接将被断开并且需要重新连接。换句话说,不仅仅是服务器必须强大 - 客户端还应该预见到连接错误并重新连接。