当 ServerSocket 抛出 IOException 并保持服务器运行时该怎么办 [英] What to do when ServerSocket throws IOException and keeping server running

查看:46
本文介绍了当 ServerSocket 抛出 IOException 并保持服务器运行时该怎么办的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Basically I want to create a rock solid server.

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

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

在IOException块中,怎么办?服务器套接字是否有问题,因此需要重新创建?例如等待几秒钟然后

In the IOException block, what to do? Is the Server socket at fault so it need to be recreated? For example wait a few seconds and then

serverSocket = ServerSocketFactory.getDefault().createServerSocket(MY_PORT);

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

However if the server socket is still OK, then it is a pity to close it and kill all previously accepted connections that are still communicating.

经过一些回答后,我尝试处理 IOException.该实现是否能保证保持服务器正常运行,并且仅在必要时才重新创建服务器套接字?

After some answers, here my attempt to deal with the IOException. Would the implementation be guaranteeing keeping the server up and only re-create server socket when only necessary?

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

推荐答案

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

If in doubt, you could try re-creating the server socket, using the same port. If the socket has been closed, then the creation will succeed and you can continue processing new connections. The old connections are gone, but that's outside of your control since the socket was closed. If the socket was not closed, then creating a new instance will fail since the port is still in use, which you can just ignore - i.e. don't replace the current server socket reference.

一般来说,客户端还应该假设连接会中断并且需要重新连接.换句话说,不仅仅是服务器必须健壮 - 客户端还应该预测连接错误并重新连接.

In general, clients should also assume that connections will be broken and that reconnection is necessary. In other words, it's not just the server that has to be robust - clients should also anticipate connection errors and reconnect.

这篇关于当 ServerSocket 抛出 IOException 并保持服务器运行时该怎么办的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆