【问题标题】:OkHttp buffers ~800kb before uploading data despite flush()尽管有flush(),但OkHttp在上传数据之前缓冲了~800kb
【发布时间】:2014-06-29 07:20:33
【问题描述】:

我正在尝试发布图片的上传进度,使用 okhttp 作为我的客户端和 mimecraft 上传它们以打包多部分文件。

当数据被写入套接字时,我添加了日志以写入字节数(如果我能正确判断,以 4kb 的块)然后上传。

问题是,虽然每次写入一大块数据时我都会在输出流上调用 flush,但在将 ~800kb 写入输出流之前似乎什么都没有上传。一旦达到这一点,它似乎上传了大约 100kb,然后应用程序将另外 100kb 写入输出流(就像它释放的空间并且可以再写入一点)并继续。

这样做的结果是(超过 1.2mb 的文件)前 800kb 几乎立即被写入/报告,然后它开始上传(通过 charles 网络软件跟踪),然后将开始读取/写入/上传 100kb在接下来的几秒钟内,一旦我将最后一个字节写入输出流,应用程序报告 100% 的上传已写入。尽管网络客户端仍在上传仍然在网络缓冲区中的最后 800kb,但它仍然存在 5-10 秒上传,然后完成请求。

有没有人有过这种经历,或者知道这是否是okhttp中的常见问题?

干杯

编辑:如果我上传一个小于 800kb 的文件,我测试了一些 250kb 和 500kb,它们都在上传前立即 100% 写入流,但 3mb 图像仍将上传 800kb,然后在大约 100kb 块,每次上传时,写入循环都会再写入 100kb。

【问题讨论】:

  • 你有没有成功。也请分享您的上传代码。
  • 有这方面的消息吗,我也遇到了同样的问题?
  • @Glenn.nz 我知道你问这个问题已经很长时间了,但你有没有找到任何好的解决方案?即使我将发送缓冲区大小设置为 16KB,它仍在缓冲 200KB 的数据。

标签: android okhttp bufferedoutputstream mimecraft


【解决方案1】:

正如@nmr 的回答所说,因为发送缓冲区太高了,正如这里的错误票所解释的那样:https://github.com/square/okhttp/issues/1078

所以我创建了一个套接字工厂,可以让您覆盖发送缓冲区大小。

https://gist.github.com/slightfoot/00a26683ea68856ceb50e26c7d8a47d0

【讨论】:

  • 嘿@Simon,覆盖发送缓冲区大小没有多大帮助。无论您设置什么缓冲区大小,它仍然会预先缓冲 200KB 的数据,但它比我想的 800KB 缓冲区要好 :)。
  • 这可能是因为我编写了这个原始代码,操作系统及其与 OkHttp 的新内置集成发生了变化。
【解决方案2】:

套接字发送缓冲区默认为高值,并且未连接刷新。我试图找到一种同步 Java 套接字的方法没有成功,默认的 Socket OutputStream 会忽略刷新。

https://github.com/square/okhttp/issues/1078

在此处设置发送缓冲区大小的可怕 hack fork:https://github.com/ACMEAtronOmatic/okhttp/tree/topic/hack-to-fix-socket-sendbuffer-size

【讨论】:

【解决方案3】:

在打开输出流之前尝试调用setFixedLengthStreamingMode(content length) 或setChunkedStreamingMode(0)。

【讨论】:

  • 我在使用正确的内容长度调用setFixedLengthStreamingMode() 后调用了connection.getOutputStream()。它肯定使用我设置的内容长度,就好像我更改它(添加 2 个字节或其他任何内容)调用失败,并且它在所有字节写入流之前开始上传。
  • 尝试这两种方法后我仍然看到报告的行为
猜你喜欢
  • 2011-10-22
  • 2021-05-06
  • 2023-01-30
  • 2015-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-11
  • 1970-01-01
相关资源
最近更新 更多