Java NIO:IOException: Broken pipe 是什么意思?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1181255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java NIO: What does IOException: Broken pipe mean?
提问by DivideByHero
For some of my Java NIO connections, when I have a SocketChannel.write(ByteBuffer)
call, it throws an IOException
: "Broken pipe".
对于我的一些 Java NIO 连接,当我SocketChannel.write(ByteBuffer)
接到电话时,它会抛出一个IOException
:“Broken pipe”。
What causes a "broken pipe", and, more importantly, is it possible to recover from that state? If it cannot be recovered, it seems this would be a good sign that an irreversible problem has occurred and that I should simply close this socket connection. Is that a reasonable assumption? Is there ever a time when this IOException
would occur while the socket connection is still being properly connected in the first place (rather than a working connection that failed at some point)?
是什么导致“管道破裂”,更重要的是,是否有可能从该状态中恢复?如果无法恢复,这似乎是一个好兆头,表明发生了不可逆转的问题,我应该简单地关闭此套接字连接。这是一个合理的假设吗?IOException
在套接字连接仍然正确连接的情况下(而不是在某些时候失败的工作连接),是否会发生这种情况?
On a side note, is it wise to always call SocketChannel.isConnected()
before attempting a SocketChannel.write()
, and if so, can I also assume that the connection is "broken" and should be closed if both SocketChannel.isConnected()
and SocketChannel.isConnectionPending()
are both false
?
附带说明一下,SocketChannel.isConnected()
在尝试 a 之前总是调用是否明智SocketChannel.write()
,如果是这样,我是否还可以假设连接“断开”并且如果两者都是SocketChannel.isConnected()
并且SocketChannel.isConnectionPending()
都应该关闭false
?
Thanks!
谢谢!
回答by jsight
Broken pipe simply means that the connection has failed. It is reasonable to assume that this is unrecoverable, and to then perform any required cleanup actions (closing connections, etc). I don't believe that you would ever see this simply due to the connection not yet being complete.
管道破裂仅意味着连接失败。假设这是不可恢复的,然后执行任何所需的清理操作(关闭连接等)是合理的。我不相信您会因为连接尚未完成而看到这一点。
If you are using non-blocking mode then the SocketChannel.connect method will return false, and you will need to use the isConnectionPending and finishConnect methods to insure that the connection is complete. I would generally code based upon the expectation that things will work, and then catch exceptions to detect failure, rather than relying on frequent calls to "isConnected".
如果您使用的是非阻塞模式,那么 SocketChannel.connect 方法将返回 false,您将需要使用 isConnectionPending 和 finishConnect 方法来确保连接完成。我通常会根据事情会正常工作的期望进行编码,然后捕获异常以检测失败,而不是依赖于频繁调用“isConnected”。
回答by Sean A.O. Harney
You should assume the socket was closed on the other end. Wrap your code with a try catch block for IOException.
您应该假设套接字在另一端关闭。使用 IOException 的 try catch 块包装您的代码。
You can use isConnected() to determine if the SocketChannel is connected or not, but that might change before your write() invocation finishes. Try calling it in your catch block to see if in fact this is why you are getting the IOException.
您可以使用 isConnected() 来确定 SocketChannel 是否已连接,但这可能会在您的 write() 调用完成之前发生变化。尝试在您的 catch 块中调用它,看看这是否就是您收到 IOException 的原因。
回答by Stephen C
What causes a "broken pipe", and more importantly, is it possible to recover from that state?
是什么导致“管道破裂”,更重要的是,是否有可能从该状态中恢复?
It is caused by something causing the connection to close. (It is not your application that closed the connection: that would have resulted in a different exception.)
它是由导致连接关闭的原因引起的。(不是您的应用程序关闭了连接:那会导致不同的异常。)
It is not possible to recover the connection. You need to open a new one.
无法恢复连接。你需要打开一个新的。
If it cannot be recovered, it seems this would be a good sign that an irreversible problem has occurred and that I should simply close this socket connection. Is that a reasonable assumption?
如果无法恢复,这似乎是一个好兆头,表明发生了不可逆转的问题,我应该简单地关闭此套接字连接。这是一个合理的假设吗?
Yes it is. Once you've received that exception, the socket won't ever work again. Closing it is is the only sensible thing to do.
是的。一旦您收到该异常,套接字将不再工作。关闭它是唯一明智的做法。
Is there ever a time when this
IOException
would occur while the socket connection is still being properly connected in the first place (rather than a working connection that failed at some point)?
IOException
在套接字连接仍然正确连接的情况下(而不是在某些时候失败的工作连接),是否会发生这种情况?
No. (Or at least, not without subverting proper behavior of the OS'es network stack, the JVM and/or your application.)
否。(或者至少,在不破坏操作系统网络堆栈、JVM 和/或您的应用程序的正确行为的情况下并非如此。)
Is it wise to always call
SocketChannel.isConnected()
before attempting aSocketChannel.write()
...
SocketChannel.isConnected()
在尝试之前总是打电话是明智的SocketChannel.write()
......
In general, it is a bad idea to call r.isXYZ()
before some call that uses the (external) resource r
. There is a small chance that the state of the resource will change betweenthe two calls. It is a better idea to do the action, catch the IOException
(or whatever) resulting from the failed action and take whatever remedial action is required.
通常,r.isXYZ()
在使用(外部)资源的某些调用之前调用是一个坏主意r
。资源状态在两次调用之间发生变化的可能性很小。执行操作、捕获IOException
失败操作导致的(或其他)结果并采取任何需要的补救措施是一个更好的主意。
In this particular case, calling isConnected()
is pointless. The method is defined to return true
if the socket was connected at some point in the past. It does not tell you if the connection is still live. The only way to determine if the connection is still alive is to attempt to use it; e.g. do a read or write.
在这种特殊情况下,调用isConnected()
毫无意义。true
如果套接字在过去的某个时间点连接过,则该方法被定义为返回。它不会告诉您连接是否仍然有效。确定连接是否还活着的唯一方法是尝试使用它;例如,读或写。
回答by user207421
Broken pipe means you wrote to a connection that is already closed by the other end.
管道损坏意味着您写入的连接已被另一端关闭。
isConnected()
does not detect this condition. Only a write does.
isConnected()
没有检测到这种情况。只有写。
is it wise to always call SocketChannel.isConnected() before attempting a SocketChannel.write()
在尝试 SocketChannel.write() 之前总是调用 SocketChannel.isConnected() 是否明智
It is pointless. The socketitself isconnected. You connected it. What maynot be connected is the connection itself, and you can only determine that by trying it.
这是毫无意义的。该插座本身就是连接。你连接了它。什么可能无法连接是连接本身,你只能判断为通过尝试它。