Java 资源尝试卡住

标签 java sockets try-with-resources

我有一个经典的服务器多客户端程序。服务器监听 ServerSocket,并为每个传入的套接字构建一个新的 Runnable 类并在 ExecuteService 中执行它。

在 Runnable 类的 run 方法中,我打开 try-with-resources block ,并且在 try 中我有一个 while 循环,它从输入流读取并写入输出流,直到收到来自客户端的 FIN 命令。一切正常,客户端成功断开连接。运行到达finally block 并打印一些内容进行测试,但它不会退出try block ,因此它不会退出run方法,并且我被困在运行中的某个地方,可能是输入流的读取方法。

如果有人感兴趣,我可以发布代码。

如何强制关闭finally中的所有内容并退出run方法?

代码:
服务器.java:

public static void main(String[] args) {
    playersReady = new ArrayList<Integer>();
    ServerSocket server = null;
    try {
        server = new ServerSocket(Consts.PORT);
        ExecutorService service = Executors.newFixedThreadPool(characters.size());
        while(playersReady.size()<characters.size()){
            RequestHandler handler = new RequestHandler(server.accept());
            service.execute(handler);
        }
        service.shutdownNow();
        service.shutdown();
        while(!service.isTerminated()){}

        System.out.println("finished");
<小时/>

RequestHandler.java

public final class RequestHandler implements Runnable {

    .....

public void run() {
    //DataOutputStream output = null;
    //DataInputStream input = null;

    try (DataOutputStream output = new DataOutputStream(socket.getOutputStream());
            DataInputStream input = new DataInputStream(socket.getInputStream())){
        // socket.setSoTimeout(500);
        handleReady(input.readUTF().split(" "), output);
        while (/*!shutdown && !socket.isClosed() && */socket.isConnected()) {

            System.out.println("check before read " + character.getId());
            String request = input.readUTF();
            System.out.println("check after read " + character.getId());

            System.out.println("-----------------------------------" + request);
            if (shutdown) {
                socket.shutdownInput();
                socket.getOutputStream().flush();
                socket.shutdownOutput();
                break;
            }
            String[] requestParser = request.split(" ");
            if (requestParser[1].equals("DMG")) {
                // handle damage request
                handleDamage(requestParser, output);
            } else if (requestParser[1].equals("BND")) {
                // handle bandage request
                handleBandage(requestParser, output);
            } else if (requestParser[1].equals("FIN")) {
                // handle finish request
                handleFin();
                if (!socket.isClosed())
                    socket.shutdownInput();
                if (!socket.isClosed()) {
                    socket.getOutputStream().flush();
                    socket.shutdownOutput();
                }
                shutdown = true;
                break;
            } else {
                break;
            }
        }
    } catch (SocketTimeoutException e) {
        System.out.println(e.getMessage());
    } catch (IOException e) {
        e.printStackTrace();
        shutdown = true;
        break;
    } catch (Throwable e) {
        e.printStackTrace();
    } finally {
        try {
            System.out.println("finished");

            if (!socket.isClosed())
                socket.shutdownInput();
            if (!socket.isClosed()) {
                socket.getOutputStream().flush();
                socket.shutdownOutput();
                socket.close();
            }
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    System.out.println("Done run");
}

...

<小时/>

最后打印出System.out.println("finished"), 但是 run 方法末尾的 System.out.println("Done run") 却没有!!

为什么?
它卡在了 run 方法中,我想是在 readUTF 调用中,但我关闭了所有资源!

最佳答案

您在该行之前返回,这就是它不运行的原因。无论如何,finally block 都会运行,因为它是一个finally block 。 finally block 总是会运行,这一规则只有一个异常(exception):System.exit(),但事实并非如此。

关于Java 资源尝试卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43871089/

相关文章:

java - 如何在 Android 中的所有 Activity 中维护变量?

Java 到 FileZilla FTP 客户端 : Socket write error

Java 抽象类建议

java - 使用什么代替 sun.net.www.protocol.http.HttpURLConnection.userAgent?

java - "Cannot find symbol: Method"但方法已在 Storm.java 中定义和声明

java - Java 套接字是否支持全双工?

node.js - 客户端socket.io和服务器端socket.id不同

f# - log4net 和 "with try"F#

java - try with resources 子句中的异常