Java NIO:IOException:Broken pipe是什么意思?

时间:2009-07-25 05:03:59

标签: java nio

对于我的一些Java NIO连接,当我进行SocketChannel.write(ByteBuffer)调用时,它会抛出IOException:“断管”。

导致“管道破裂”的原因是什么,更重要的是,是否可以从该状态恢复?如果它无法恢复,似乎这是一个好的迹象,表明发生了不可逆转的问题,我应该简单地关闭这个套接字连接。这是一个合理的假设吗?在套接字连接仍然是首先正确连接时(而不是某个时候失败的工作连接),是否有时间会出现IOException

另一方面,在尝试SocketChannel.isConnected()之前总是调用SocketChannel.write()是明智的,如果是这样,我是否也可以假设连接已“断开”并且如果两者都应该关闭{ {1}}和SocketChannel.isConnected()都是SocketChannel.isConnectionPending()

谢谢!

4 个答案:

答案 0 :(得分:94)

  

是什么导致“破管”,更重要的是,是否可以从该状态恢复?

它是由导致连接关闭的东西引起的。 (关闭连接不是你的应用程序:这会导致一个不同的异常。)

无法恢复连接。你需要开一个新的。

  

如果无法恢复,似乎这是一个很好的迹象,表明发生了不可逆转的问题,我应该简单地关闭这个套接字连接。这是一个合理的假设吗?

是。一旦收到该异常,套接字将无法再次运行。关闭它是唯一明智的做法。

  

在套接字连接首次正确连接时(而不是某个时刻失败的工作连接),是否有时间会出现IOException

没有。 (或者至少,并非没有颠覆OS网络堆栈,JVM和/或您的应用程序的正确行为。)


  

在尝试SocketChannel.isConnected()之前始终致电SocketChannel.write()是否明智...

通常,在使用(外部)资源r.isXYZ()的某个调用之前调用r是个坏主意。 两次调用之间的资源状态很可能会发生变化。最好的做法是执行操作,捕获失败操作产生的IOException(或其他),并采取任何必要的补救措施。

在这种特殊情况下,调用isConnected()毫无意义。如果套接字在过去的某个时刻连接,则该方法被定义为返回true 。它不会告诉您连接是否仍然有效。确定连接是否仍然存在的唯一方法是尝试使用它;例如做一个读或写。

答案 1 :(得分:22)

断管只是意味着连接失败。可以合理地假设这是不可恢复的,然后执行任何所需的清理操作(关闭连接等)。我不相信你会因为连接尚未完成而看到这一点。

如果使用非阻塞模式,则SocketChannel.connect方法将返回false,您将需要使用isConnectionPending和finishConnect方法来确保连接完成。我通常会根据事情的预期进行编码,然后捕获异常来检测故障,而不是依赖频繁调用“isConnected”。

答案 2 :(得分:17)

管道损坏意味着您已写入已被另一端关闭的连接。

isConnected()未检测到此情况。只写一次。

  

在尝试SocketChannel.write()

之前总是调用SocketChannel.isConnected()是明智的吗?

毫无意义。 套接字本身连接。你连接了它。 可能未连接的是连接本身,您只能通过尝试来确定它。

答案 3 :(得分:1)

您应该假设套接字已在另一端关闭。使用try catch块包装代码以获取IOException。

您可以使用isConnected()来确定SocketChannel是否已连接,但在write()调用完成之前可能会更改。尝试在catch块中调用它,看看实际上这是否是你获得IOException的原因。