0

I am creating a android application that will be used to upload the zip file from local file system to the server. Below is my file upload code.

 protected Object doInBackground(Object[] objects) {
        try {
    String boundary = "===" + System.currentTimeMillis() + "===";
                String LINE_FEED = "\r\n";
                String charset;
                String fieldName = "uploadFile";
                URL url = new URL("http://hridhaanirs.com/REST-TEST/upload");
                HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
                httpConn.setUseCaches(false);
                httpConn.setDoOutput(true); // indicates POST method
                httpConn.setDoInput(true);
                httpConn.setRequestProperty( "Accept-Encoding", "" );
                httpConn.setRequestProperty("Content-Type",
                        "multipart/form-data; boundary=" + boundary);
                httpConn.setRequestProperty("User-Agent", "CodeJava Agent");
                httpConn.setRequestProperty("Test", "Bonjour");
                OutputStream outputStream = httpConn.getOutputStream();
                PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream, "UTF-8"),
                        true);
                outputStream = httpConn.getOutputStream();
                File file=new File((String)objects[0]);
                String fileName = file.getName();
                writer.append("--" + boundary).append(LINE_FEED);
                writer.append("Content-Disposition: form-data; name=\"" + fieldName
                        + "\"; filename=\"" + fileName + "\"")
                        .append(LINE_FEED);
                writer.append(
                        "Content-Type: "
                                + URLConnection.guessContentTypeFromName(fileName))
                        .append(LINE_FEED);
                writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);

                writer.append(LINE_FEED);
                writer.flush();

                FileInputStream inputStream = new FileInputStream(file);
                FileReader fileReader=new FileReader(file);
                int buff;
                while((buff=fileReader.read())!=-1){
                    outputStream.write(buff);
                }
                outputStream.flush();
                inputStream.close();

                writer.append(LINE_FEED);
                writer.flush();
                List<String> response = new ArrayList<>();
                writer.append(LINE_FEED).flush();
                writer.append("--" + boundary + "--").append(LINE_FEED);
                writer.close();

                int status = httpConn.getResponseCode();
                if (status == HttpURLConnection.HTTP_OK) {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
                    String line = null;
                    while ((line = reader.readLine()) != null) {
                        response.add(line);
                    }
                    reader.close();
                    httpConn.disconnect();
                }
                return response;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }

I see below exception when executing debugging above code.

02-06 11:13:36.863 32495-32598/com.tech.mds.mdsconnect I/System.out: [OkHttp] sendRequest>>
02-06 11:13:41.886 32495-32598/com.tech.mds.mdsconnect W/System.err: java.net.SocketException: sendto failed: EPIPE (Broken pipe)
02-06 11:13:41.913 32495-32598/com.tech.mds.mdsconnect W/System.err:     at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:586)
02-06 11:13:41.935 32495-32598/com.tech.mds.mdsconnect W/System.err:     at libcore.io.IoBridge.sendto(IoBridge.java:555)
02-06 11:13:41.957 32495-32598/com.tech.mds.mdsconnect W/System.err:     at java.net.PlainSocketImpl.write(PlainSocketImpl.java:513)
02-06 11:13:41.978 32495-32598/com.tech.mds.mdsconnect W/System.err:     at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:42)
02-06 11:13:41.998 32495-32598/com.tech.mds.mdsconnect W/System.err:     at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:271)
02-06 11:13:42.014 32495-32598/com.tech.mds.mdsconnect W/System.err:     at com.android.okio.Okio$1.write(Okio.java:70)
02-06 11:13:42.038 32495-32598/com.tech.mds.mdsconnect W/System.err:     at com.android.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:116)
02-06 11:13:42.055 32495-32598/com.tech.mds.mdsconnect W/System.err:     at com.android.okio.RealBufferedSink.write(RealBufferedSink.java:44)
02-06 11:13:42.076 32495-32598/com.tech.mds.mdsconnect W/System.err:     at com.android.okhttp.internal.http.RetryableSink.writeToSocket(RetryableSink.java:77)
02-06 11:13:42.098 32495-32598/com.tech.mds.mdsconnect W/System.err:     at com.android.okhttp.internal.http.HttpConnection.writeRequestBody(HttpConnection.java:240)
02-06 11:13:42.119 32495-32598/com.tech.mds.mdsconnect W/System.err:     at com.android.okhttp.internal.http.HttpTransport.writeRequestBody(HttpTransport.java:77)
02-06 11:13:42.138 32495-32598/com.tech.mds.mdsconnect W/System.err:     at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:631)
02-06 11:13:42.160 32495-32598/com.tech.mds.mdsconnect W/System.err:     at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:398)
02-06 11:13:42.182 32495-32598/com.tech.mds.mdsconnect W/System.err:     at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:342)
02-06 11:13:42.205 32495-32598/com.tech.mds.mdsconnect W/System.err:     at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:520)
02-06 11:13:42.223 32495-32598/com.tech.mds.mdsconnect W/System.err:     at com.tech.mds.mdsconnect.FileUpload.doInBackground(FileUpload.java:88)
02-06 11:13:42.240 32495-32598/com.tech.mds.mdsconnect W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:292)
02-06 11:13:42.258 32495-32598/com.tech.mds.mdsconnect W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
02-06 11:13:42.275 32495-32598/com.tech.mds.mdsconnect W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
02-06 11:13:42.293 32495-32598/com.tech.mds.mdsconnect W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
02-06 11:13:42.308 32495-32598/com.tech.mds.mdsconnect W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
02-06 11:13:42.316 32495-32598/com.tech.mds.mdsconnect W/System.err:     at java.lang.Thread.run(Thread.java:818)
02-06 11:13:42.334 32495-32598/com.tech.mds.mdsconnect W/System.err: Caused by: android.system.ErrnoException: sendto failed: EPIPE (Broken pipe)
02-06 11:13:42.403 32495-32598/com.tech.mds.mdsconnect W/System.err:     at libcore.io.Posix.sendtoBytes(Native Method)
02-06 11:13:42.413 32495-32598/com.tech.mds.mdsconnect W/System.err:     at libcore.io.Posix.sendto(Posix.java:206)
02-06 11:13:42.423 32495-32598/com.tech.mds.mdsconnect W/System.err:     at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278)
02-06 11:13:42.433 32495-32598/com.tech.mds.mdsconnect W/System.err:     at libcore.io.IoBridge.sendto(IoBridge.java:553)
02-06 11:13:42.438 32495-32598/com.tech.mds.mdsconnect W/System.err:    ... 20 more

ZIP file contains couple of images and a .txt file. If I upload .txt file then it works successfully. Moreover I used same code in JAVA SE environment and uploaded same zip file successfully. So definitely It seems to be an environmental issue.

Mayank Vaid
  • 330
  • 1
  • 7
  • 18
  • https://stackoverflow.com/questions/14622700/android-socket-java-net-socketexception-sendto-failed-epipe-broken-pipe – Umair Feb 06 '18 at 05:51
  • Use retrofit and multipart. [refer][1] and [this][2] [1]: https://futurestud.io/tutorials/retrofit-2-how-to-upload-files-to-server [2]: https://androidmads.blogspot.in/2016/06/upload-file-to-server-using-retrofit-in.html – Raul Feb 06 '18 at 06:20
  • @Umair.. I saw that post. However in my case i am getting the exception at int status = httpConn.getResponseCode(); – Mayank Vaid Feb 06 '18 at 08:44
  • @MayankVaid yes that means you are not getting anything from the server it is closing the connection. Either there is something wrong with your request or like the answer said you are exceeding the upload limit. – Umair Feb 06 '18 at 08:49
  • @Umair Upload limit shouldnt be a problem since server is already configured to take about 1 gb of data. In my case its is hardly 10 mb. second this I am not able to understand why same code is working absolutely fine in Java SE env. – Mayank Vaid Feb 06 '18 at 08:56
  • also in android the code is able to upload ".txt" files .. – Mayank Vaid Feb 06 '18 at 08:58
  • Of the same size as that zip file? – greenapps Feb 06 '18 at 09:33
  • @greenapps So on reading your comment I tried uploading ".txt" file for larger size and got the same exception trace. By doing multiple hit and trial I see that error is there for the files greater than 1 mb. But my server application can have maximum 1 gb of file and same I am able to upload though server application UI. So why I am getting this error through android. Does android itself has some limitations that needs to overrided ? – Mayank Vaid Feb 06 '18 at 16:42
  • Do you mean 1MB and 1 GB ? Or what is it? – greenapps Feb 06 '18 at 17:08
  • `int buff; while((buff=fileReader.read())!=-1){ outputStream.write(buff); }`. It is of course terrible that your loop handles only one byte at a time. Declare a buffer. Read inthe buffer. Then write ojt the contents of the buffer. – greenapps Feb 06 '18 at 17:11
  • yeah !! thats what I did . I used buffer and now everything works like charm. I saw this while debugging, code was taking lot of time in the loop itself and therefore the peer might be closing the connection. Thanks a lot @greenapps :) – Mayank Vaid Feb 06 '18 at 17:38

2 Answers2

0
  1. The server has closed the connection, either because your hand-implemented chunking protocol is incorrect or because you have exceeded an upload limit.

  2. Throw your hand-implemented chunking protocol away and use HttpURLConnection.setChunkedStreamingMode().

user207421
  • 305,947
  • 44
  • 307
  • 483
0

I modified the reading code as suggested by @greenapps and everything worked. It seems that reading one byte at a time made the request horribly slow and therefore connection was getting terminated. Used buffer to read specific amount of bytes at a time and write to the output stream.

Mayank Vaid
  • 330
  • 1
  • 7
  • 18