【问题标题】:unexpected end of stream retrofit流改造意外结束
【发布时间】:2020-08-17 01:58:47
【问题描述】:

我有一个 Android 应用程序向 Flask 中的 REST API 发出 http 请求。我正在使用带有 okhttp3 的 Retrofit2 向带有 Raspbian Lite 的 Raspberry Pi 上托管的服务器发出请求。 我的问题是有时我得到一个 IOException -> java.net.ProtocolException: unexpected end of stream 但它有时会发生,有时它会完美运行。 http客户端搭建如下:

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
        @NotNull
        @Override
        public Response intercept(@NotNull Chain chain) throws IOException {
            Request original = chain.request();

            Request request = original.newBuilder()
                    .header("User-Agent","myUserAgent")
                    .header("Connection","close")
                    .addHeader("Accept-Encoding", "identity")
                    .method(original.method(),original.body())
                    .build();

            return chain.proceed(request);
        }
    });
Retrofit retrofit=null;
    try {
         retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                .client(httpClient.build())
                .build();

    }catch (Exception e){
         //Log.d

    }
ApiService API_SERVICE=null;
    try{
        API_SERVICE = retrofit.create(ApiService.class);
    }catch (Exception e){
        //Log.d
    }

    return API_SERVICE;

我尝试过使用和不使用日志拦截器,使用 Accept-Encoding: identity 和 Conecction: close。但它不起作用。 答案的 Content-Lenght 是 4339(由邮递员表示),在拦截器中它也表示 4339 这是我得到的例外:

我在 Android API 28 中使用带有模拟器的 Android Studio。我的电脑和树莓派都通过以太网电缆连接到互联网。 我不明白为什么有时请求有效,而有时它直接进入 onFailure。 在服务器上,我总是得到一个 200 代码。请求被处理并正确返回响应。 我还能尝试什么?

【问题讨论】:

    标签: android retrofit2 okhttp ioexception


    【解决方案1】:

    看来问题出在 Android Studio 模拟器上。我尝试将我的智能手机连接到 android studio 并在另一部智能手机上安装 APK,但问题没有重现。

    【讨论】:

    【解决方案2】:

    看起来像这个问题:https://github.com/square/okhttp/issues/2738。所以试试这个:

    要么:

    .addHeader("连接", "关闭")

    或者: .retryOnConnectionFailure(true)

    【讨论】:

    • 我已经有“连接,关闭”。与 retryOnConnectFailure 是一样的。我现在有 OkHttpClient.Builder httpClient = new OkHttpClient.Builder().retryOnConnectionFailure(true);
    • 奇怪。根据您的 StackTrace,它非常适合。我仍然觉得这是同样的问题,但在你的情况下还有其他事情发生。
    • 另外,检查一下 - stackoverflow.com/questions/61422009/… 意思可能是服务器问题吗?
    • 我的问题出在okHttp的Http1Codec $FixedLengthSource.read()方法中。服务器没有提供承诺的内容长度,但为什么呢?当请求有效时,服务器给我的响应与无效时相同。 codota.com/code/java/classes/…
    • 也许你应该考虑重新打开这个因不可重现而关闭的问题 - github.com/square/okhttp/issues/3589
    【解决方案3】:

    我也遇到了这个问题,我发现只有当我同时调用两个具有具有不同参数的相同 URL 的函数(函数 A 和 B)时才会发生这种情况。函数 A 获得成功响应后,有时函数 B 收到错误 java.net.ProtocolException: unexpected end of stream

    所以我的解决方法是在函数 A 获得成功响应后调用函数 B

    【讨论】:

      【解决方案4】:

      改造偶尔也会出现此错误。当服务器端发生 504 网关超时 问题时。所以在android端没有问题。这个答案可能会对某人有所帮助。

      【讨论】:

        【解决方案5】:

        我试过 [this][https://stackoverflow.com/questions/5528850/how-do-you-connect-localhost-in-the-android-emulator/59217370#59217370] 并且成功了! (我的问题是 localhost IP 192.168.x.x)

        进入模拟器的设置->设置->代理->选择手动代理配置->输入你的本地IP地址。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-09-20
          • 2015-11-17
          • 1970-01-01
          • 1970-01-01
          • 2017-05-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多