Java 中的 BufferedReader 在尝试从已关闭的套接字中读取时无法触发异常

BufferedReader in Java fails to trigger exception when trying to read from closed socket

我正在连接一个 TCP 套接字,并在该套接字的线程中为 I/O 打开一个缓冲的 reader,然后在缓冲的 reader 上使用 readLine 读取数据:

try {
  socket = new Socket(targetHost, targetPort);
  ou = new PrintWriter(socket.getOutputStream(), true);
  in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

  while (true) {
    message = in.readLine();
    ...
    process the data
    ...
  }
} catch (Exception e) {
  e.printStackTrace();
  return;
}

只要有连接就可以正常工作。但是当 TCP 连接的另一端意外断开时,在大约 75% 的情况下,该线程永远不会意识到另一端已经断开,并且任何从缓冲的 reader 中读取的尝试都会简单地产生一个 "null" 字符串,但没有抛出异常,我无法关闭线程,因为它不知道另一端已经消失了。在大约 25% 的情况下,线程被终止(也没有产生异常),但这会产生预期的结果,我只需要线程在 TCP 连接断开时消失。

我尝试使用它来确定连接是否存在:

boolean connected = socket.isConnected() && !socket.isClosed();

但这行不通,总是 returns 当另一边已经离开并且线程继续咀嚼时为真。

有什么想法吗?

重点基本上是:"works as designed".

返回null的reader其实就是:"no more data; I am done here".

参见javadoc

Returns:包含行内容的字符串,不包括任何行终止字符,如果已到达流末尾则为 null

换句话说:关闭套接字在这里被视为"normal"操作;因此也不例外。换句话说:您必须更改代码以检查结果是否为 readLine() returns null;如果是这样,您就知道插座不见了。