如何修复java.net.SocketException:管道破裂?
我使用ApacheCommonsHTTP客户端调用url,使用post方法发布参数,它很少抛出以下错误如何修复java.net.SocketException:管道破裂?,java,exception,post,sockets,Java,Exception,Post,Sockets,我使用ApacheCommonsHTTP客户端调用url,使用post方法发布参数,它很少抛出以下错误 java.net.SocketException: Broken pipe at java.net.SocketOutputStream.socketWrite0(Native Method) at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92) at jav
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)
有人能建议是什么导致了此异常以及如何调试它吗?这是由以下原因引起的:
- 最常见的情况是,在另一端已经关闭连接时写入连接李>
- 不太常见的情况是,对等方在不读取其端已挂起的所有数据的情况下关闭连接
还有第三个原因,我不在此赘述,但涉及到对等方故意采取措施重置连接,而不是正确关闭连接。我通过FTP服务器实现了数据下载功能,并在恢复下载时发现了相同的异常。
要解决此异常,您必须始终断开与上一个会话的连接,并创建新的客户端实例和与服务器的新连接。同样的方法对HTTPClient也有帮助。在我们的例子中,我们在应用服务器上执行负载测试时遇到了这种情况。问题是,我们需要向JVM添加额外的内存,因为它已经用完了。这解决了问题
尝试增加JVM可用的内存,或者在出现这些错误时监视内存使用情况。所有打开的流和连接都需要正确关闭,因此下次尝试使用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.
JavaDoc:
传入连接指示的最大队列长度(a)
请求连接)设置为50。如果连接指示到达
当队列已满时,连接被拒绝
例如,您应该增加ServerSocket的“backlog”参数
int backlogSize = 50 ;
new ServerSocket(port, backlogSize);
问题可能是您部署的文件没有使用正确的RMI方法更新。检查RMI接口是否更新了参数,或更新了客户端没有的数据结构。或者您的RMI客户端没有与服务器版本不同的参数
这只是一个有根据的猜测。重新部署我的服务器应用程序的类文件并重新测试后,“管道断裂”的问题消失了。原因是远程对等方关闭了其套接字(例如崩溃),因此,如果您尝试向他写入数据,例如,您将得到此结果。要解决此问题,请保护(try catch)之间的读/写套接字操作,然后在catch中管理丢失连接情况(续订连接、停止程序等):
上面的答案说明了出现这种情况的原因
java.net.SocketException:breaked pipe
:另一端关闭了连接。我想分享一下我遇到它时的经历:
内容类型
头被错误地设置为大于请求正文的实际大小(实际上根本没有正文)Servlet.service()引发异常
java.net.SocketTimeoutException:null
java.net.SocketException:管道破裂
,因为客户端关闭了它有时候,tomcat不会抛出断开的pip异常,因为超时异常关闭了连接,为什么这样的差异也让我困惑 SocketException:管道破裂,是由于“另一端”(客户端或服务器)在代码读取或写入连接时关闭连接造成的 在从应用程序控制之外的客户端或服务器接收流量的客户端/服务器应用程序中,这是一个非常常见的异常。例如,客户端是一个浏览器。如果浏览器发出Ajax调用,和/或用户只是关闭页面或浏览器,那么这可能会有效地意外终止所有通信。基本上,当另一端终止其应用程序时,您会看到这个错误,而您并没有预料到 如果在应用程序中遇到此异常,则意味着您应该检查发生IO(输入/输出)的代码,并使用try/catch块将其包装以捕获此IOException。然后,由您决定如何处理这种半有效的情况 在您的情况下,最早仍有控制权的地方是调用
HttpMethodDirector.executeWithRetry
——因此,请确保调用包含try/catch块,并以您认为合适的方式处理它
我强烈建议不要在调试/跟踪级别以外的任何级别记录SocketException中断管道特定错误。否则,可以通过填充日志将其用作DOS(拒绝服务)攻击的一种形式。尝试针对这种常见场景对应用程序进行强化和负面测试。我在开发一个侦听特定TCP的简单Java应用程序时遇到了同样的问题。通常情况下,我没有问题,但当我运行一些压力测试时,我注意到一些连接由于错误而中断
套接字写入异常
经过调查,我找到了解决问题的办法。我知道这个问题很老了,但我更愿意分享我的解决方案,有人会发现它很有用
问题出在ServerSocket创建上。我从Javadoc中了解到,默认限制为50个挂起的套接字。如果您尝试打开另一个连接,这些连接将被拒绝。解决办法仅仅在于改变现状
try {
/* your code */
} catch (SocketException e) {
e.printStackTrace();
/* insert your failure processings here */
}
public void postRequest() {
Security.insertProviderAt(Conscrypt.newProvider(), 1);
System.out.println("mediafilename-->>" + mediaFileName);
String[] dirarray = mediaFileName.split("/");
String file_name = dirarray[6];
//Thread.sleep(10000);
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file",file_name, RequestBody.create(MediaType.parse("video/mp4"), new File(mediaFileName))).build();
OkHttpClient okHttpClient = new OkHttpClient();
// ExecutorService executor = newFixedThreadPool(20);
// Request request = new Request.Builder().post(requestBody).url("https://192.168.0.31:5000/uploader").build();
Request request = new Request.Builder().url("http://192.168.0.31:5000/uploader").post(requestBody).build();
// Request request = new Request.Builder().url("http://192.168.0.31:5000").build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
//
call.cancel();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),"Something went wrong:" + " ", Toast.LENGTH_SHORT).show();
}
});
e.printStackTrace();
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
});
System.out.println("Response ; " + response.body().toString());
// Toast.makeText(getApplicationContext(), response.body().toString(),Toast.LENGTH_LONG).show();
System.out.println(response);
}
});