Java.net.ProtocolException: 流意外结束

17

我遇到了一个奇怪的问题,也无法进行调试。我已经实现了上传数据流的逻辑,并且正在使用 Volley 进行操作。我稍微定制了一下 HurlStackaddBodyIfExists API 的逻辑,以便能够处理 "application/octet-stream" 类型的主体内容。

我的逻辑是为了向用户发布进度,以便可以更新 UI,指示用户上传的进度,以下是我实现同样功能的逻辑。

            int toRead = length; // File length
            byte[] data = new byte[4096];
            connection.setDoOutput(true);
            if(length != -1) {
                connection.setFixedLengthStreamingMode(length);
            } else {
                connection.setChunkedStreamingMode(4096);
            }

            OutputStream os;
            int i;
            int count;

            os = connection.getOutputStream();
            int progress= 0;

               try {
                    for(i = 0; (count= is.read(data)) > 0; ++i) { // is, is not null and contains a valid input stream
                        os.write(data, 0, count); // at this line am getting unexpected end of stream
                        progress+= count;
                        if(i % 20 == 0) {
                            rs.deliverProgress(progress, 0L);
                            progress= 0;
                        }
                    }

                    os.flush();
                } finally {
                    if(is != null) {
                        is.close();
                    }

                    if(os != null) {
                        os.close();
                    }

                }

在执行上述代码时,我遇到了这个问题,尽管我已经验证了输出流不为空,输入流也不为空,但它在第一次读取循环中失败了,我看到它已经读取了4096个字节,然后尝试写入相同的内容。

java.net.ProtocolException: unexpected end of stream
            at com.android.okhttp.internal.http.HttpConnection$FixedLengthSink.close(HttpConnection.java:326)
            at com.android.okio.RealBufferedSink.close(RealBufferedSink.java:174)
            at com.android.okio.RealBufferedSink$1.close(RealBufferedSink.java:142)

非常感谢在调试过程中提供的任何帮助。


1
尝试使用BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "utf-8")); writer.write(...);代替os.write(...) - BNK
1
你是否正在使用日志拦截器?如果是,请将其移除并运行。这是因为日志拦截器会耗尽输入或输出流,然后在实际处理即将进行时触发此异常。 - Debanjan
3
我在模拟器中遇到了这个问题。 - Zar E Ahmer
1
@BNK认为你拯救了我的一天,因为你帮我处理了大量的JSON数据。 - zakaria
6个回答

10
这可能会对你有所帮助:这里
当预期的字节数(通常在响应的content-length头中设置)大于实际响应数据时,FixedLengthInputStream会抛出该异常。
请检查content-length头是否正确。(如果您为内容长度提供自己的值,请确保它是正确的。)
看到设置输入流的代码也会有所帮助。

1
这种情况发生在我的安卓模拟器上,但在我的实体安卓设备上没有发生。 我正在从安卓应用程序向运行在我的笔记本电脑上的0.0.0.0的flask服务器发送GET请求。
要在模拟器上修复它,请在模拟器代理中添加服务器的IP地址。 请参见如何设置Android模拟器代理设置 我遇到的确切问题是retrofit意外流结尾

1
我同意Vainquit的回答。如果你在Android模拟器上遇到这个问题,可能在真实设备上不会出现。当我使用绕过开发中允许将http连接到本地服务器时,就会出现这个问题。当我在真实的云服务器上设置了https后,这个问题就解决了。在真实设备上也对我起作用。

0

你的数据长度可能是未知的,这有点奇怪。是媒体文件吗?还是直播流呢?

不管怎样,我尝试上传我的直播流数据,但出现了相同的错误。我在连接中添加了这个设置,解决了我的问题。 转移编码:分块传输。

("setChunkedStreamingMode" 不起作用,我仍然不知道为什么。)


0

已经解决了,请在头部添加“Accept-Encoding”、“identity”,这样服务器端就会收到命令,不会修改响应,然后发送回客户端。


请问您能分享一些该头部参数的示例数值吗? - Sathish Gadde

0
如果你已经在代码中检查了所有地方,并尝试了stackoverflow和github中的每个解决方案,但问题仍然存在,并且你只在模拟器上测试了代码,那么你应该尝试在真实设备上运行代码。也许它会起作用,也许不会,但如果你感到绝望,那就试试看,认真对待。当我发现我的代码在模拟器上每次都有bug,但在我的手机上成功运行时,我感到很惊讶。此外,该代码还在其他人的Android模拟器上成功运行。所以我猜测我的Android Studio配置有些问题,我找不出来。我不知道为什么会发生这种情况,就像我们不知道为什么“清理项目/无效缓存”有时比任何解决方案都更有效一样。

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