意外的流结束 retrofit

3
我有一个Android应用程序,它向Flask中的REST API发出http请求。我使用Retrofit2和okhttp3向运行在安装了Raspbian Lite的树莓派上的服务器发送请求。我的问题是有时会收到IOException -> java.net.ProtocolException:意外的流结束。但这种情况有时发生,其他时候它可以完美地工作。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(由Postman指示),在拦截器中也指示为4339。 这是我得到的异常:

enter image description here

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

6

看起来问题出在 Android Studio 模拟器上。我已经尝试连接我的智能手机到 Android Studio 上并在另一台智能手机上安装 APK,但问题没有再现。


1
尝试这个:https://dev59.com/pW035IYBdhLWcg3wQtog#55606008 - Behnawwm

2

我尝试了[这个][https://dev59.com/pW035IYBdhLWcg3wQtog#59217370],并且它起作用了!(我的问题是与本地IP地址192.168.x.x有关)

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


使用 127.0.0.1 作为本地代理也会有所帮助。 - Mahdi Javaheri

1

我已经有了“连接,关闭”。 使用retryOnConnectFailure是一样的。 现在我有了 OkHttpClient.Builder httpClient = new OkHttpClient.Builder().retryOnConnectionFailure(true); - Botellita Taponzito
奇怪。根据您的堆栈跟踪,它非常匹配。我仍然觉得这是相同的问题,但在您的情况下还有其他事情正在发生。 - Dmitri
此外,请查看此内容 - https://dev59.com/Nrroa4cB1Zd3GeqPnJVw 的意思是可能是服务器的问题吗? - Dmitri
我的问题出现在okHttp的Http1Codec $ FixedLengthSource.read()方法中。服务器没有提供承诺的内容长度,但为什么?当请求正常工作和不工作时,服务器给我相同的响应。 https://www.codota.com/code/java/classes/okhttp3.internal.http1.Http1Codec$FixedLengthSource - Botellita Taponzito
也许您应该考虑重新打开此问题,因为它被关闭了,原因是无法重现 - https://github.com/square/okhttp/issues/3589 - Dmitri

1
我也遇到了这个问题,发现只有在同时调用具有不同参数的相同URL的函数A和B时才会出现。在函数A获得成功响应后,有时函数B会收到错误java.net.ProtocolException: unexpected end of stream
因此,我的解决方法是在函数A获得成功响应后调用函数B。

0

这个错误有时也会由Retrofit返回。当服务器端出现504网关超时问题时,就会出现这种情况。因此,Android端没有问题。这个答案可能会对某些人有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接