异常 - 如何修复.SocketException:管道坏了?
我正在使用apache commons http客户端使用post方法调用url来发布参数,并且它很少抛出以下错误。
.SocketException: Broken pipe
at .SocketOutputStream.socketWrite0(Native Method)
at .SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at .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)
有人可以建议导致此异常的原因以及如何调试它吗?
10个解决方案
67 votes
这是因为当另一端已经关闭连接时写入连接。
因此,您的应用程序协议定义不明确或已实现。
user207421 answered 2019-05-30T23:09:37Z
23 votes
在我们的案例中,我们在应用服务器上执行负载测试时遇到了这种情况。 问题是我们需要为JVM添加额外的内存,因为它已经用完了。 这解决了这个问题。
尝试增加JVM可用的内存,或者在出现这些错误时监视内存使用情况。
Dave answered 2019-05-30T23:10:07Z
6 votes
SocketException:管道损坏,是由代码读取或写入连接时关闭连接的“另一端”(客户端或服务器)引起的。
这是客户端/服务器应用程序中非常常见的例外,它从应用程序控件之外的客户端或服务器接收流量。 例如,客户端是浏览器。 如果浏览器进行Ajax调用,和/或用户只是关闭页面或浏览器,那么这可以有效地杀死所有通信。 基本上,只要另一端终止其应用程序,您就会看到此错误,并且您没有预料到它。
如果您在应用程序中遇到此异常,那么这意味着您应检查发生IO(输入/输出)的代码,并使用try / catch块将其包装以捕获此IOException。 然后,由您决定如何处理这种半有效的情况。
在您的情况下,您仍然可以控制的最早的地方是对HttpMethodDirector.executeWithRetry的调用 - 因此请确保使用try / catch块包装调用,并按照您认为合适的方式处理它。
我强烈建议不要在调试/跟踪级别以外的任何地方记录SocketException-Broken Pipe特定错误。 否则,这可以通过填充日志作为DOS(拒绝服务)攻击的一种形式。 针对这种常见情况,尝试并强化并对您的应用程序进行负面测试。
AndyGee answered 2019-05-30T23:11:00Z
4 votes
所有开放的流和& 连接需要正确关闭,所以下次我们尝试使用urlConnection对象时,它不会抛出错误。 例如,以下代码更改为我修复了错误。
之前:
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
bw.write("Some text");
bw.close();
out.close();
后:
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.
Murali Mohan answered 2019-05-30T23:11:27Z
1 votes
我已经通过FTP服务器实现了数据下载功能,并在恢复下载时也发现了相同的异常。要解决此异常,您将始终必须断开与上一个会话的连接,并创建客户端的新实例以及与服务器的新连接。 同样的方法也可能对HTTPClient有所帮助。
Naeem Ahmad answered 2019-05-30T23:11:51Z
1 votes
原因是远程对等体关闭了它的套接字(例如崩溃),所以如果你试图向他写数据,你就会得到这个。 要解决这个问题,请在以下插件之间插入读/写操作:
try {
/* your code */
} catch (SocketException e) {
e.printStackTrace();
/* insert your failure processings here */
}
elhadi dp ıpɐɥןǝ answered 2019-05-30T23:12:15Z
0 votes
以上答案说明了这个原因.SocketException: Broken pipe:另一端关闭了连接。 我想分享一下遇到它时发生的事情:
在客户端的请求中,.SocketException: Broken pipe标头错误地设置为大于请求主体实际上(实际上根本没有主体)
tomcat套接字中的底层服务正在等待那个大小的正文数据(http在TCP上,通过封装和...确保传递)
当60秒过期时,tomcat抛出异常时间:.SocketException: Broken pipe
由于超时异常,客户端收到状态码为500的响应。
客户端关闭连接(因为它收到响应)。
tomcat抛出.SocketException: Broken pipe因为客户关闭了它。
有时,tomcat不会抛出破坏的pip异常,因为超时异常关闭连接,为什么这样的差异也让我感到困惑。
Tiina answered 2019-05-30T23:13:27Z
0 votes
在我的情况下,这发生是因为版本不是pom.xml中的动态变量。
pom.xml中的版本是“1.0.SNAPSHOT”
我改成了
$ {}版本
第一个构建已通过但下一个构建试图部署到已关闭连接的同一位置。
更改版本后,我已经解决了。
Vineela Thonupunuri answered 2019-05-30T23:14:24Z
-1 votes
JavaDoc的:
传入连接指示的最大队列长度(a 请求连接)设置为50.如果连接指示到达 当队列已满时,连接被拒绝。
例如,您应该增加ServerSocket的“backlog”参数
int backlogSize = 50 ;
new ServerSocket(port, backlogSize);
TheSecond answered 2019-05-30T23:14:56Z
-1 votes
问题可能是您使用正确的RMI方法更新了部署的文件。 检查您的RMI接口是否已更新参数,或客户端没有的更新数据结构。 或者您的RMI客户端没有与服务器版本不同的参数。
这只是一个有根据的猜测。 在重新部署我的服务器应用程序的类文件并重新测试之后,“Broken pipe”的问题就消失了。
JonAar answered 2019-05-30T23:15:28Z