(Java,Socket)BufferedReader阻塞线程,无法.close()

时间:2017-09-15 10:34:46

标签: java multithreading sockets server client

所以我为我的覆盆子pis编写了一个Client-Server-application - 来处理服务器上的多个客户端我总是为每个客户端套接字打开一个新的“ClientMessageListener”-thread。

我试图创建一个在我希望ServerSocket关闭时调用的destroy链。它遍历每个线程并调用ClientMessageListener的destroy-method,它应该关闭连接资源,然后关闭套接字本身。

我的客户端处理程序如下所示:

package com.imnos.piserver.server.serversocket.client;

import com.imnos.piserver.server.serversocket.ServerRequestController;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

/**
* @author simon
*/
public class ClientMessageListener implements Runnable {

    private static final ServerRequestController SRC
            = ServerRequestController.getInstance();

    private Socket clientSocket = null;

    private PrintWriter out = null;
    private InputStreamReader inputStream = null;
    private BufferedReader in = null;

    ClientMessageListener(final Socket clientSocket) {
        this.clientSocket = clientSocket;
        this.initDataStream();
    }

    /**
     * @return
     */
    synchronized boolean destroyClientMessageListener() {

        if (this.clientSocket == null) {
            return false;
        }

        if (this.in != null) {

            try {

                this.in.close(); // Method stucks here

            } catch (IOException ignore) {
                ignore.printStackTrace();
            } finally {
                this.in = null;
            }

        }

        if (this.inputStream != null) {

            try {

                this.inputStream.close();

            } catch (IOException ignore) {
                ignore.printStackTrace();
            } finally {
                this.inputStream = null;
            }

        }

        if (this.out != null) {

            this.out.close();
            this.out = null;

        }

        return true;
    }

    /**
     * @return
     */
    private synchronized boolean initDataStream() {

        if (this.clientSocket == null) {
            return false;
        }

        if (this.clientSocket.isClosed()) {
            return false;
        }

        try {

            this.out = new PrintWriter(
                    this.clientSocket.getOutputStream(), true);

            this.inputStream = new InputStreamReader(
                    this.clientSocket.getInputStream());

            this.in = new BufferedReader(this.inputStream);

            return true;

        } catch (IOException ex) {

            this.destroyClientMessageListener();
            ex.printStackTrace();

        }

        return false;
    }

    /**
     *
     */
    @Override
    public void run() {

        if (in != null) {

            String strInput;

            try {

                while ((strInput = this.in.readLine()) != null) {

                    final boolean success
                        = SRC.handleIncoming(
                            this.clientSocket, strInput);

                }

            } catch (IOException ignore) {
                ignore.printStackTrace();
            }

        }

    }

}

一切正常,我期待this.in.readLine() - 当我在destroy()方法中关闭资源时调用抛出IOException,这样线程才会结束。但是,在调用this.in.close()时,destroy-method会阻塞,并且绝对不会抛出异常。

即使Thread.getCurrentThread.interrupt()也不起作用,我不明白为什么。是否有一个干净的解决方案来关闭资源并结束run() - 方法?

1 个答案:

答案 0 :(得分:1)

关闭套接字以进行输入。这将导致readLine()返回null,这将导致正在读取套接字的线程关闭它并退出。

相关问题