由于 ECONNRESET(连接由对等方重置),大多数情况下使用 retrofit2 上传二进制文件失败

Uploading binary file with retrofit2 most of the times fail because of ECONNRESET (Connection reset by peer)

我正在使用 retrofit2 上传二进制图像文件:

File file = new File(filePath);
    RequestBody requestBody = new ProgressRequestBody(
            MediaType.parse("application/octet-stream"),
            file,
            this);

    Call<ResponseBody> call = service.uploadFile(requestBody);

    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call,
                               Response<ResponseBody> response) {

            if (!response.isSuccessful()) {
                Toasti.showS("fail");
                return;
            }

            Log.v("Upload", "success");
            UploadFileOutput uploadFileOutput = new UploadFileOutput();
            try {
                uploadFileOutput =
                        new Gson().fromJson(response.body().string(), UploadFileOutput.class);
            } catch (IOException e) {
                e.printStackTrace();
            }


  ImageLoader.getInstance().displayImage(uploadFileOutput.imageSrc, giftImageview);
            }

        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            Log.e("Upload error:", t.getMessage());
            Toasti.showS("fail");
        }
    });

但大多数时候(有时它工作正常!)因为这个错误而失败:

sendto failed: ECONNRESET (Connection reset by peer)

我阅读了很多 post 和教程:

Getting “SocketException : Connection reset by peer” in Android

retrofit.RetrofitError: sendto failed: ECONNRESET (Connection reset by peer)

但是其中 none 帮助了我。

我用 postman 测试了 api 方法,它总是没有任何错误!

经过几天的测试和搜索,我发现我应该将 okhttp 客户端的超时时间增加 readTimeoutreadTimeout:

longTimeOutHttpClient = new OkHttpClient.Builder()
            .readTimeout(120, TimeUnit.SECONDS)
            .connectTimeout(120, TimeUnit.SECONDS)
            .build();
    longTimeoutRetrofitBuilder = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .client(httpClient);
    longTimeOutRetrofit = longTimeoutRetrofitBuilder.baseUrl(URIs.BASE_URL + 
    URIs.API_VERSION).build();

    longTimeoutService = longTimeOutRetrofit.create(RestAPI.class);

此错误是由于文件太大和网速低导致连接超时。