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

Java中的BufferedReader在尝试从关闭的套接字读取时未能触发异常,java,multithreading,sockets,tcp,bufferedreader,Java,Multithreading,Sockets,Tcp,Bufferedreader,我正在连接一个TCP套接字,并在其自己的线程中为该套接字上的I/O打开一个缓冲读取器,然后使用缓冲读取器上的readLine读取数据: try { socket = new Socket(targetHost, targetPort); ou = new PrintWriter(socket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(socket.getInputStream()))

我正在连接一个TCP套接字,并在其自己的线程中为该套接字上的I/O打开一个缓冲读取器,然后使用缓冲读取器上的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%的情况下,该线程从未意识到另一端已经消失,任何尝试从缓冲读取器读取的行为都只会产生一个“null”字符串,但不会抛出任何异常,我无法关闭线程,因为它不知道另一端已经离开。在大约25%的情况下,线程被终止(也不会生成异常),但这会产生期望的结果,我只需要在TCP连接断开时线程离开即可

我尝试使用此选项来确定连接是否处于活动状态:

boolean connected = socket.isConnected() && !socket.isClosed();
但这不起作用,当另一方离开并且线程继续咀嚼时,总是返回true

有什么想法吗?

要点基本上是:“按设计工作”

读取器返回null实际上意味着:“没有更多的数据;我在这里完成了”

见:

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

换言之:插座关闭在这里被视为“正常”操作;因此,也不例外。换句话说:您必须更改代码以检查
readLine()
的结果是否返回null;如果是这样,你就知道插座不见了。

要点基本上是:“按设计工作”

读取器返回null实际上意味着:“没有更多的数据;我在这里完成了”

见:

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


换言之:插座关闭在这里被视为“正常”操作;因此,也不例外。换句话说:您必须更改代码以检查
readLine()
的结果是否返回null;如果是这样的话,你就知道什么插座不见了。

定义“不见了”。按照TCP连接的工作方式,如果另一方关闭了连接,您应该会看到异常。然而,如果对方只是变得遥不可及(例如,电缆被拔出,或服务器被关闭,在TCP发现问题之前会有一个很长的超时时间。离开意味着另一端的程序决定退出。不是崩溃,而是退出。这意味着它关闭TCP连接。当连接断开时,客户端应该会检测到一个事件,否?Wher它说它应该抛出一个异常吗?当
readLine()
返回null(根据Javadoc,这意味着“流结束”)时,您为什么不停止读取?这就是您要查找的“事件”。另一端不构成“闭合套接字”。它构成一个断开的连接。定义“断开”。按照TCP连接的工作方式,如果另一方关闭了连接,您应该会看到异常。但是,如果另一方无法访问(例如,电缆被拔出,或服务器被关闭,在TCP发现问题之前会有一个很长的超时时间。离开意味着另一端的程序决定退出。不是崩溃,而是退出。这意味着它关闭TCP连接。当连接断开时,客户端应该会检测到一个事件,否?Wher它说它应该抛出异常吗?当
readLine()时,为什么不停止阅读
返回null,根据Javadoc,这意味着“流结束”。这是您要查找的“事件”。另一端不构成“关闭的套接字”。它构成断开的连接。但如上所述,TCP连接的另一端不只是拔出,而是关闭,即套接字关闭。应该有det该事件是可复制的。@Balthasar有。
readLine()
返回空值。@EJP谢谢。我正在寻找一个现有的问题作为dup结束,但没有找到这个问题。另一方面,这两个向上的投票让我超过了25K。好啦!所以,我不介意。@EJP在谷歌上到处搜索,但那个dup昨天没有出现。@Balthasar它已经存在了4-1/2年了。但是如上所述,问题的另一面TCP连接不只是拔掉插头,而是关闭,即插座关闭。应该有可检测的事件。@Balthasar有。
readLine()
返回空值。@EJP谢谢。我正在寻找一个现有的问题作为dup结束,但没有找到这个问题。另一方面,这两个向上投票让我超过了25K。好啦!所以,我不介意。@EJP在谷歌上到处搜索,但那个dup昨天没有出现。@Balthasar它已经出现了4-1/2年了。