如何修复 java.net.SocketException: Broken pipe?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2309561/
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
How to fix java.net.SocketException: Broken pipe?
提问by
I am using apache commons http client to call url using post method to post the parameters and it is throwing the below error rarely.
我正在使用 apache commons http 客户端使用 post 方法调用 url 来发布参数,并且它很少抛出以下错误。
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105)
at java.io.FilterOutputStream.write(FilterOutputStream.java:80)
at org.apache.commons.httpclient.methods.ByteArrayRequestEntity.writeRequest(ByteArrayRequestEntity.java:90)
at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
Can someone suggest what is causing this Exception and how to debug it?
有人可以建议导致此异常的原因以及如何调试它吗?
回答by user207421
This is caused by:
这是由以下原因引起的:
- most usually, writing to a connection when the other end has already closed it;
- less usually, the peer closing the connection without reading all the data that is already pending at his end.
- 最常见的是,在另一端已经关闭连接时写入连接;
- 不太常见的是,对等方关闭连接而不读取所有已经挂起的数据。
So in both cases you have a poorly defined or implemented application protocol.
因此,在这两种情况下,您的应用程序协议定义或实施都很糟糕。
There is a third reason which I will not document here but which involves the peer taking deliberate action to reset rather than properly close the connection.
还有第三个原因,我不会在这里记录,但涉及对等方采取刻意的行动来重置而不是正确关闭连接。
回答by Naeem Ahmad
I have implemented data downloading functionality through FTP server and found the same exception there too while resuming that download. To resolve this exception, you will always have to disconnect from the previous session and create new instance of the Client and new connection with the server. This same approach could be helpful for HTTPClient too.
我已经通过 FTP 服务器实现了数据下载功能,并且在恢复下载时也发现了相同的异常。要解决此异常,您将始终必须与之前的会话断开连接并创建客户端的新实例以及与服务器的新连接。同样的方法也可能对 HTTPClient 有帮助。
回答by Dave
In our case we experienced this while performing a load test on our app server. The issue turned out that we need to add additional memory to our JVM because it was running out. This resolved the issue.
在我们的案例中,我们在应用服务器上执行负载测试时遇到了这种情况。事实证明,我们需要向 JVM 添加额外的内存,因为它已经用完了。这解决了问题。
Try increasing the memory available to the JVM and or monitor the memory usage when you get those errors.
尝试增加 JVM 可用的内存,或者在出现这些错误时监视内存使用情况。
回答by Murali Mohan
All the open streams & connections need to be properly closed, so the next time we try to use the urlConnection object, it does not throw an error. As an example, the following code change fixed the error for me.
所有打开的流和连接都需要正确关闭,所以下次我们尝试使用 urlConnection 对象时,它不会抛出错误。例如,以下代码更改为我修复了错误。
Before:
前:
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
bw.write("Some text");
bw.close();
out.close();
After:
后:
OutputStream os = urlConnection.getOutputStream();
OutputStream out = new BufferedOutputStream(os);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
bw.write("Some text");
bw.close();
out.close();
os.close(); // This is a must.
回答by TheSecond
JavaDoc:
The maximum queue length for incoming connection indications (a request to connect) is set to 50. If a connection indication arrives when the queue is full, the connection is refused.
Java文档:
传入连接指示(连接请求)的最大队列长度设置为 50。如果队列已满时连接指示到达,则拒绝连接。
You should increase "backlog" parameter of your ServerSocket, for example
例如,您应该增加 ServerSocket 的“backlog”参数
int backlogSize = 50 ;
new ServerSocket(port, backlogSize);
回答by JonAar Livernois
The issue could be that your deployed files are not updated with the correct RMI methods. Check to see that your RMI interface has updated parameters, or updated data structures that your client does not have. Or that your RMI client has no parameters that differ from what your server version has.
问题可能是您部署的文件没有使用正确的 RMI 方法进行更新。检查您的 RMI 接口是否更新了参数,或更新了客户端没有的数据结构。或者您的 RMI 客户端没有与您的服务器版本不同的参数。
This is just an educated guess. After re-deploying my server application's class files and re-testing, the problem of "Broken pipe" went away.
这只是一个有根据的猜测。重新部署我的服务器应用程序的类文件并重新测试后,“断管”问题消失了。
回答by elhadi dp ?p????
The cause is that the remote peer closes its socket (crash for example), so if you try to write data to him for example, you will get this. to solve that, protect read/write to socket operations between (try catch), then manage the lose connection case into the catch (renew connection, stop program, ...etc):
原因是远程对等方关闭了它的套接字(例如崩溃),因此如果您尝试向他写入数据,例如,您会得到这个。为了解决这个问题,保护读/写之间的套接字操作(try catch),然后将丢失连接的情况管理到catch中(更新连接,停止程序等):
try {
/* your code */
} catch (SocketException e) {
e.printStackTrace();
/* insert your failure processings here */
}
回答by Tiina
The above answers illustrate the reason for this java.net.SocketException: Broken pipe
: the other end closed the connection. I would like to share experience what happened when I encountered it:
上面的答案说明了原因java.net.SocketException: Broken pipe
:另一端关闭了连接。我想分享一下我遇到它时发生的事情:
- in a client's request, the
Content-Type
header is mistakenly set larger than request body actually is (in fact there was no body at all) - the bottom service in tomcat socket was waiting for that sized body data (http is on TCP which ensures delivery by encapsulating and ...)
- when 60 seconds expired, tomcat throws time out exception:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception java.net.SocketTimeoutException: null
- client receives a response with status code 500 because of the timeout exception.
- client close connection (because it receives response).
- tomcat throws
java.net.SocketException: Broken pipe
because client closed it.
- 在客户端的请求中,
Content-Type
标头被错误地设置为大于请求正文的实际大小(实际上根本没有正文) - tomcat 套接字中的底层服务正在等待那个大小的主体数据(http 在 TCP 上,它通过封装和……来确保交付)
- 当 60 秒到期时,tomcat 抛出超时异常:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception java.net.SocketTimeoutException: null
- 由于超时异常,客户端收到状态码为 500 的响应。
- 客户端关闭连接(因为它收到响应)。
- tomcat 抛出
java.net.SocketException: Broken pipe
是因为客户端关闭了它。
Sometimes, tomcat does not throw broken pip exception, because timeout exception close the connection, why such a difference is confusing me too.
有时,tomcat 不会抛出损坏的 pip 异常,因为超时异常关闭了连接,为什么这样的差异也让我感到困惑。
回答by AndyGee
SocketException: Broken pipe, is caused by the 'other end' (The client or the server) closing the connection while your code is either reading from or writing to the connection.
SocketException: Broken pipe, 是由“另一端”(客户端或服务器)在您的代码读取或写入连接时关闭连接引起的。
This is a very common exception in client/server applications that receive traffic from clients or servers outside of the application control. For example, the client is a browser. If the browser makes an Ajax call, and/or the user simply closes the page or browser, then this can effectively kill all communication unexpectedly. Basically, you will see this error any time the other end terminates their application, and you were not anticipating it.
这是客户端/服务器应用程序中非常常见的异常,这些应用程序从应用程序控制之外的客户端或服务器接收流量。例如,客户端是浏览器。如果浏览器发出 Ajax 调用,和/或用户只是关闭页面或浏览器,那么这会有效地意外终止所有通信。基本上,每当另一端终止其应用程序时,您都会看到此错误,而您并没有预料到它。
If you experience this Exception in your application, then it means you should check your code where the IO (Input/Output) occurs and wrap it with a try/catch block to catch this IOException. It is then, up to you to decide how you want to handle this semi-valid situation.
如果您在应用程序中遇到此异常,则意味着您应该检查发生 IO(输入/输出)的代码,并使用 try/catch 块将其包装以捕获此 IOException。然后,由您决定如何处理这种半有效的情况。
In your case, the earliest place where you still have control is the call to HttpMethodDirector.executeWithRetry
- So ensure that call is wrapped with the try/catch block, and handle it how you see fit.
在您的情况下,您仍然可以控制的最早位置是调用HttpMethodDirector.executeWithRetry
- 因此请确保使用 try/catch 块包装调用,并按照您认为合适的方式处理它。
I would strongly advise against logging SocketException-Broken Pipe specific errors at anything other than debug/trace levels. Else, this can be used as a form of DOS (Denial Of Service) attack by filling up the logs. Try and harden and negative-test your application for this common scenario.
我强烈建议不要在调试/跟踪级别以外的任何级别记录 SocketException-Broken Pipe 特定错误。否则,这可以通过填写日志来用作 DOS(拒绝服务)攻击的一种形式。针对这种常见情况尝试强化和负面测试您的应用程序。