0

I was going to make an classifier with Tensorflow, so I used the flaskand requests library to send files from a client to a flask server running my classifier.

The flask server's code is:

# Create flask app
app = Flask(__name__)
# Set upload floder
app.config['UPLOAD_FOLDER'] = './upload'
# Max content length
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024

app.run(host='0.0.0.0')

@app.route('/upload', methods=['POST'])
def upload_file():
    # Check file upload field
    if 'file' not in request.files:
        return ''
    file = request.files['file']
    # Return if file does not have name
    if file.filename == '':
        return ''
    # Save in upload folder
    audio_file = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
    file.save(audio_file)

The python client's code is:

import requests 

url = 'http://www.testurl.com/upload'

files = {'file': open('sound/sample/sample/carhorn/1.wav', 'rb')}
r = requests.post(url, files=files)
print(r.text)

I wanted to connect the flask server with an Android device, so I rewrote this Python client code to java. I used the 'okhttp 3.5.0' library to send multipart/form data.

The java client's code is:

public void uploadFile(String filepath) throws CustomException {
    String requestURL = "http://www.testurl.com/upload";
    File file = new File(filepath);
    OkHttpClient client = new OkHttpClient();
    RequestBody requestBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("file", file.getName(),
                    RequestBody.create(MediaType.parse("audio/wav"), file))
            .build();

    Request request = new Request.Builder()
            .url(requestURL)
            .post(requestBody)
            .build();

    Response response = null;

    try {
        response = client.newCall(request).execute();
    } catch (IOException e) {
        e.printStackTrace();
    }

    if (response == null || !response.isSuccessful()) {
        Log.w("Server", "Unable to upload to server.");
    } else {
        Log.v("Server", "Upload was successful.");
    }
}

But with this code, It makes this 'EPIPE' error:

03-12 00:01:59.434 29084-29756/com.ishs.fylproject.classifierclient W/System.err: java.net.SocketException: sendto failed: EPIPE (Broken pipe)
    03-12 00:01:59.436 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:542)
    03-12 00:01:59.436 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at libcore.io.IoBridge.sendto(IoBridge.java:511)
    03-12 00:01:59.436 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at java.net.PlainSocketImpl.write(PlainSocketImpl.java:500)
    03-12 00:01:59.436 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at java.net.PlainSocketImpl.-wrap1(PlainSocketImpl.java)
    03-12 00:01:59.437 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266)
    03-12 00:01:59.437 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okio.Okio$1.write(Okio.java:78)
    03-12 00:01:59.437 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okio.AsyncTimeout$1.write(AsyncTimeout.java:179)
    03-12 00:01:59.439 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:171)
    03-12 00:01:59.439 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okio.RealBufferedSink.write(RealBufferedSink.java:41)
    03-12 00:01:59.440 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http1.Http1Codec$FixedLengthSink.write(Http1Codec.java:287)
    03-12 00:01:59.440 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:171)
    03-12 00:01:59.440 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okio.RealBufferedSink.writeAll(RealBufferedSink.java:99)
    03-12 00:01:59.440 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.RequestBody$3.writeTo(RequestBody.java:118)
    03-12 00:01:59.441 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.java:171)
    03-12 00:01:59.441 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.MultipartBody.writeTo(MultipartBody.java:113)
    03-12 00:01:59.441 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:48)
    03-12 00:01:59.441 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    03-12 00:01:59.441 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
    03-12 00:01:59.441 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    03-12 00:01:59.442 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    03-12 00:01:59.442 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
    03-12 00:01:59.442 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    03-12 00:01:59.442 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    03-12 00:01:59.442 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
    03-12 00:01:59.442 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    03-12 00:01:59.443 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
    03-12 00:01:59.444 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    03-12 00:01:59.445 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    03-12 00:01:59.445 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179)
    03-12 00:01:59.446 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.RealCall.execute(RealCall.java:63)
    03-12 00:01:59.446 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at com.ishs.fylproject.classifierclient.SoundAlert.uploadFile(SoundAlert.java:249)
    03-12 00:01:59.446 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at com.ishs.fylproject.classifierclient.SoundAlert.copyWaveFile(SoundAlert.java:298)
    03-12 00:01:59.447 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at com.ishs.fylproject.classifierclient.SoundAlert.stopRecording(SoundAlert.java:212)
    03-12 00:01:59.447 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at com.ishs.fylproject.classifierclient.SoundAlert.access$400(SoundAlert.java:66)
    03-12 00:01:59.447 29084-29756/com.ishs.fylproject.classifierclient W/System.err:     at com.ishs.fylproject.classifierclient.SoundAlert$ExampleThread.run(SoundAlert.java:386)

Is there a way to fix this error? Or is there any way to send multipart/form data on android like the Python client code I wrote?

Thanks,

EDITED

I edited the response = client.newCall(request).execute(); in the java client code to

client.newCall(request).enqueue(new Callback() {
    @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }

     @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

            Headers responseHeaders = response.headers();
            for (int i = 0, size = responseHeaders.size(); i < size; i++) {
                System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
            }

            System.out.println(response.body().string());
        }
    }
    );
} catch (Exception e) {
    e.printStackTrace();
}

but still makes this error:

03-12 22:05:59.565 26156-26525/com.ishs.fylproject.classifierclient W/System.err: java.net.SocketException: sendto failed: EPIPE (Broken pipe)
03-12 22:05:59.565 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:546)
03-12 22:05:59.565 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at libcore.io.IoBridge.sendto(IoBridge.java:515)
03-12 22:05:59.565 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at java.net.PlainSocketImpl.write(PlainSocketImpl.java:504)
03-12 22:05:59.565 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:37)
03-12 22:05:59.565 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266)
03-12 22:05:59.565 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okio.Okio$1.write(Okio.java:78)
03-12 22:05:59.565 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okio.AsyncTimeout$1.write(AsyncTimeout.java:179)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:171)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okio.RealBufferedSink.write(RealBufferedSink.java:41)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http1.Http1Codec$FixedLengthSink.write(Http1Codec.java:287)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:171)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okio.RealBufferedSink.writeAll(RealBufferedSink.java:99)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.RequestBody$3.writeTo(RequestBody.java:118)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.java:171)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.MultipartBody.writeTo(MultipartBody.java:113)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:48)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.RealCall$AsyncCall.execute(RealCall.java:129)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
03-12 22:05:59.575 26156-26525/com.ishs.fylproject.classifierclient W/System.err:     at java.lang.Thread.run(Thread.java:818)

1 Answers1

0

You would get a broken pipe when your flask code returned prematurely.

app.run(host='0.0.0.0')  # App is running here with no routes

@app.route('/upload', methods=['POST'])
def upload_file():
    # Check file upload field
    if 'file' not in request.files:
        return ''
    file = request.files['file']
    # Return if file does not have name
    if file.filename == '':
        return ''

Both the return '' or at the end of the function, you return None with no explicit return type, so OkHttp can't really know if a response.isSuccessful() is true although an empty string would probably be a 200 response code in Flask.

It would be better if you can make Flask return actual Response objects that have meaningful messages so that you can debug the error better.


Secondly, you need to move the app.run() statement to the end of all the routes, otherwise, it's not setup correct.

Flask tutorial - 404 Not Found


I'm not entirely sure that you need a multipart request, though.

You can post a file directly. See https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/PostFile.java

Community
  • 1
  • 1
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • I think my python server has a problem. When I remove the `app.run(host='0.0.0.0')`and send from localhost, It works very well, but when I put that code(app.run), It makes `('Connection aborted.', error(32, 'Broken pipe'))` this error. – F.YLSunghwan Mar 12 '17 at 17:47
  • You need `0.0.0.0` for the server to be globally visible. Your Android app doesn't send to `localhost`, because that would be the Android device **itself** – OneCricketeer Mar 12 '17 at 17:52
  • 1
    Oh, this is finally solved. I moved the code `app.run(host='0.0.0.0')` last line of my python code, and It worked! http://stackoverflow.com/questions/25383187/flask-tutorial-404-not-found This helped me to move the code `app.run(host='0.0.0.0')`. Thanks for adding comments on my question! – F.YLSunghwan Mar 12 '17 at 17:56
  • Oh, yeah. Completely read over that... But I was kind of correct. Your code was running "prematurely" – OneCricketeer Mar 12 '17 at 17:57