用 HttpURLConnection 如何读取较大的数据流?

2017-12-19 16:13:55 +08:00
 Marsss
临时开发的一个 app,Java 没来得及多看,基础比较弱,各位多指点。

这样的,我试着用 HttpURLConnection 来向我的 flask 服务发起一个 http 请求,返回值,是一个比较大的 json 格式的数据


只截取了一部分,大概有几十 K 的大小,也不算是很大。然后就老是出现一个很奇怪的时候,debug 发现 app 这边接收了一小部分就报错了。


SocketException: recvfrom failed: ECONNRESET 这个错误,网上出现的还不少,但是原因也比较多,我测试给他返回一个比较小的值时,就是正常的,那么我这边的原因也比较明确了,就是数据比较大,我接收的姿势可能太简单或者哪里没有设置对,导致数据没有接收完的时候,连接不明原因的断开了。

这是代码


开始以为是超时的问题,设置再长都没用。用浏览器直接访问这个连接,都没问题,而且速度非常快。所以,应该不是超时的问题。

也试着换了 okhttp 这种比较新的包,仍然是会有这个问题,折腾几天了。
8119 次点击
所在节点    Android
6 条回复
AlisaDestiny
2017-12-19 17:15:48 +08:00
http://blog.csdn.net/a859522265/article/details/7965971

帮你找的。可能会对你有帮助。
heyang
2017-12-19 17:32:05 +08:00
https://tools.ietf.org/html/rfc7233
拆分 - 合并, 记得校验
TommyG
2017-12-20 09:34:20 +08:00
或许你应该将 InputStream 改为 BufferedInputStream .
我觉得既然有几十 K 的大小,为什么不能当成一个文件进行下载?
Marsss
2017-12-20 11:18:41 +08:00
@AlisaDestiny @heyang 谢谢二位,这些资料我也认真看过,设置 connection 为 close 并没有解决问题
@TommyG 改成 BufferedInputStream 也是一样的问题,我试着将返回的数据缩短一些就都正常,数据量一旦超过某个值,debug 的时候就会看到 while 那里,只写了一部分就跳到异常了,异常那里显示的是连接被重置了。

看起来就是数据量大了之后(实际上数据也就是几十 k,不算很大了),无法保持持久的数据读取。
Marsss
2017-12-21 11:05:59 +08:00
野生码畜爬坑小记:

又花了一天的时间来爬这个坑,暂时算是爬出来了。把一些东西写在这里,也许会有人需要参考。

首先,我图中的代码不严谨:
response.append(new String(b)) 这里由于 read(b)函数的特性,并不能保证每次都能填满 b 这个字节组,如果在某次循环中,read(b)只更新了 b 的一部分值,另外一部分值则还保留了上一次的值,这样 append 到 response 里,会出现问题。

那么我们应该读到多少就 append 多少才行,改成这样:
response.append(new String(b,0,len, charset))

然而这个优化并没有解决我遇到的问题,我的程序在 debug 的时候依然还是只能读到一部分数据就跳异常了,我突然想到我之前使用的本机的浏览器测试访问正常的,那么直接使用模拟器的浏览器去访问呢,结果让我很意外,genymotion 模拟器自带的浏览器竟然也只读取到了一部分值,这 TM 至少说明了,也许我的代码并没有什么大毛病,可能是环境引起的问题。

于是我在网上随便下载了一个雷电模拟器,用它自带的浏览器能正常获取到数据。于是直接使用这个雷电模拟器来 debug,这次终于正常了。。。看来被各种推荐的神器 genymotion 在 win 环境下也是可能存在一些问题的啊,MD,折腾了好几天了。

另外,我觉得我这个帖子的问题可能问的有点不对,我其实并不需要知道怎么去用 httpurlconnection 读取一个较大的数据,不过我在搜索资料的过程中,可能对这个问题有一些思路,也顺便写在这里吧。

我们其实可以在我们的服务端的 response 里面加一个 Accept-Ranges: bytes 栏,这样客户端就可以使用多线程分段请求的方式来读取这个大文件了,既解决了数据过大引起的读取差错,又提高了读取效率。详见 http 协议。

看来还是不能太浮躁,心想着用了几天 python,Java 看都不看,撸起袖子就抄代码,终究还是要吃亏。

就这样吧,谢谢各位。
vjnjc
2017-12-21 15:08:45 +08:00
HttpURLConnection 作为整个 android 系统的基础,我感觉是不会有这样的问题的。亲测至少下十几 MB 的图片都没问题,数据也下载过几百 KB 的数据,没遇到过问题,建议楼主使用框架化的 response

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/416019

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX