因此,我为我的树莓派编写了一个客户端-服务器应用程序 - 为了处理服务器上的多个客户端,我总是为每个客户端套接字打开一个新的“ClientMessageListener”线程。
我尝试创建一个销毁链,当我想要关闭 ServerSocket 时会调用该销毁链。它遍历每个线程并调用 ClientMessageListener 的 destroy 方法,该方法应该关闭连接资源,然后关闭套接字本身。
我的客户端处理程序如下所示:
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();
}
}
}
}
一切正常,当我在 destroy() 方法中关闭资源时,我希望 this.in.readLine() 调用抛出 IOException,以便线程结束。但是,当调用 this.in.close() 时, destroy 方法会阻塞,并且绝对不会抛出异常。
即使 Thread.getCurrentThread.interrupt() 也不起作用,我不知道为什么。是否有一个干净的解决方案来关闭资源并结束 run() 方法?
最佳答案
关闭输入套接字。这将导致 readLine() 返回 null,从而导致正在读取套接字的线程将其关闭并退出。
关于java - (Java, Socket) BufferedReader 阻塞线程,无法 .close(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46237542/