95

对于我的一些 Java NIO 连接,当我SocketChannel.write(ByteBuffer)接到电话时,它会抛出一个IOException:“Broken pipe”。

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

SocketChannel.isConnected()附带说明一下,在尝试 a 之前总是打电话是否明智SocketChannel.write(),如果是这样,我是否还可以假设连接已“断开”并且如果两者都应该关闭并且SocketChannel.isConnected()两者SocketChannel.isConnectionPending()都是false

谢谢!

4

4 回答 4

109

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

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

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

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

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

IOException当套接字连接首先仍然正确连接(而不是在某个时候失败的工作连接)时,是否曾经发生过这种情况?

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


SocketChannel.isConnected()在尝试SocketChannel.write()...之前总是打电话是否明智?

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

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

于 2009-07-25T05:52:51.460 回答
23

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

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

于 2009-07-25T05:12:39.420 回答
21

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

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

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

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

于 2010-11-20T11:47:10.253 回答
1

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

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

于 2009-07-25T05:17:00.630 回答