Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何修复java.net.SocketException:管道破裂?_Java_Exception_Post_Sockets - Fatal编程技术网

如何修复java.net.SocketException:管道破裂?

如何修复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

我使用ApacheCommonsHTTP客户端调用url,使用post方法发布参数,它很少抛出以下错误

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
:另一端关闭了连接。我想分享一下我遇到它时的经历:

  • 在客户端的请求中,
    内容类型
    头被错误地设置为大于请求正文的实际大小(实际上根本没有正文)
  • tomcat套接字中的底层服务正在等待那个大小的主体数据(http在TCP上,它通过封装和…)来确保交付)
  • 当60秒过期时,tomcat抛出超时异常: 路径为[]的上下文中Servlet[dispatcherServlet]的
    Servlet.service()引发异常
    java.net.SocketTimeoutException:null
  • 由于超时异常,客户端收到状态代码为500的响应
  • 客户端关闭连接(因为它接收响应)
  • tomcat抛出
    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);
    
                }
            });