Java NIO: IOException: Broken pipe 是啥意思? [复制]

Posted

技术标签:

【中文标题】Java NIO: IOException: Broken pipe 是啥意思? [复制]【英文标题】:Java NIO: What does IOException: Broken pipe mean? [duplicate]Java NIO: IOException: Broken pipe 是什么意思? [复制] 【发布时间】:2010-11-13 22:53:28 【问题描述】:

对于我的一些 Java NIO 连接,当我有一个 SocketChannel.write(ByteBuffer) 调用时,它会抛出一个 IOException: "Broken pipe"。

是什么导致“管道破裂”,更重要的是,是否有可能从该状态中恢复?如果无法恢复,这似乎是一个好兆头,表明发生了不可逆转的问题,我应该简单地关闭这个套接字连接。这是一个合理的假设吗?是否曾经有过这种IOException 会在套接字连接仍然正确连接的情况下发生的时候(而不是在某个时候失败的工作连接)?

附带说明,在尝试SocketChannel.write() 之前始终调用SocketChannel.isConnected() 是否明智,如果是这样,我是否还可以假设连接已“断开”并且如果SocketChannel.isConnected() 和@ 都应该关闭,则应该关闭987654327@都是false

谢谢!

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

如果您之前没有管道,您将无法获得破损的管道。如果之前没有连接,您将无法获得失败的连接。这个答案的最后一段是正确的,但无关紧要。【参考方案2】:

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

您可以使用 isConnected() 来确定 SocketChannel 是否已连接,但这可能会在您的 write() 调用完成之前发生变化。尝试在你的 catch 块中调用它,看看这是否就是你得到 IOException 的原因。

【讨论】:

在这种异常情况下,isConnected() 无论如何都会返回 true。将其读作“套接字在过去的某个时间点连接” 这个答案的最后一段是完全不正确的。 isConnected() 没有检测到这种情况。【参考方案3】:

是什么导致了“断管”,更重要的是,是否有可能从该状态中恢复?

这是由于某些原因导致连接关闭。 (关闭连接的不是您的应用程序:这会导致不同的异常。)

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

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

是的。一旦您收到该异常,套接字将不再工作。关闭它是唯一明智的做法。

在套接字连接仍然正确连接(而不是在某个时候失败的工作连接)时,是否曾经发生过 IOException

没有。 (或者至少,不会破坏操作系统网络堆栈、JVM 和/或您的应用程序的正确行为。)


在尝试SocketChannel.write() 之前总是调用SocketChannel.isConnected() 是否明智...

一般来说,在使用(外部)资源r 的调用之前调用r.isXYZ() 是个坏主意。资源状态在两次调用之间 发生变化的可能性很小。执行该操作是一个更好的主意,捕获由失败操作导致的IOException(或其他)并采取任何需要的补救措施。

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

【讨论】:

【参考方案4】:

Broken pipe 表示您写入的连接已被另一端关闭。

isConnected() 没有检测到这种情况。只有写入。

在尝试 SocketChannel.write() 之前总是调用 SocketChannel.isConnected() 是否明智

这是没有意义的。 socket 本身 已连接。你连接了它。 可能没有连接的是连接本身,你只能通过尝试来确定。

【讨论】:

以上是关于Java NIO: IOException: Broken pipe 是啥意思? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

java.io.IOException: Connection reset by peer和java.io.IOException: Connection timed out。Socket

急!急!急!服务起来一直报java.io.IOException: Connection reset by peer这个怎么解决!

Netty : java.io.IOException: Connection reset by peer

Java nio NonBlocking NIO

Java NIO案例

Java nio 的文件处理