iPad / iPhone上的HTTP字节范围协议客户端行为 [英] HTTP byte range protocol client behaviour on iPad/iPhone

查看:174
本文介绍了iPad / iPhone上的HTTP字节范围协议客户端行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在测试 HTTP servlet实现(由BalusC友情分享)支持 HTTP字节范围请求

我有发现不同的HTTP客户端之间存在一些特殊的差异,并且想知道我是否遗漏了任何东西。我使用了> 2G mp4视频文件进行测试,并使用Wireshark捕获数据包。这大概就是这样:

I have found some peculiar differences between different HTTP clients, and was wondering if I am not missing anything. I have used a >2G mp4 video file for my tests and was capturing packets with Wireshark. This is roughly what happens:


  • 三星Galaxy SII:

  • Samsung Galaxy SII:


  • 文件的HTTP GET请求到来,要求字节范围 [0; <几乎是文件的结尾>]

  • 服务器响应,开始流式传输文件

  • 每个后续块都在相同HTTP响应的范围内提供。没有发送新的HTTP请求(除非视频被快速转发到某个位置)。流式代码块非常简单,它读取 RandomAccessFile输入并通过 OutputStream输出 > byte [] buffer :

  • HTTP GET request for file comes, asking for byte range [0; <almost the end of the file>]
  • server responds, starts to stream the file
  • each subsequent chunk is served within the bounds of the same HTTP response. No new HTTP request is sent (unless the video is fast forwarded to a certain position). Streaming code chunk for this is quite simple, it reads RandomAccessFile input and writes to OutputStream output via byte[] buffer:

while ((read = input.read(buffer)) > 0) {
    output.write(buffer, 0, read);
}



  • 文件的HTTP GET请求到来,要求字节范围 [0; <几乎是文件的结尾>]

  • 服务器响应,开始流式传输文件

  • iPad获得了大块或两个,然后单方面决定停止接受来自服务器的字节,并为文件的下一个块发出单独的 GET 请求。新的范围边界是例如 [100,几乎是文件的结尾] 。视频显示正常。

  • 从第2步开始重复循环。左边界始终向文件末尾移动。

  • HTTP GET request for file comes, asking for byte range [0; <almost the end of the file>]
  • server responds, starts to stream the file
  • iPad gets a chunk or two and then unilaterally decides to stop accepting bytes from the server and issues a separate GET request for the next chunk of the file. New range boundaries are e.g. [100, almost the end of the file]. The video is shown OK.
  • cycle repeats again from step 2. Left boundary always moves towards the end of the file.

我没有调查连接的确切方式。可能是iPad停止发送TCP ACK数据包,我想这并不重要。

I didn't investigate how exactly the connection is terminated. It could be that iPad stops sending TCP ACK packets, I suppose this doesn't really matter that much.

我的问题是,对于每个终止的连接,我得到 java.net.SocketException:管道损坏异常。这不仅会污染日志(这是一个小问题/可解决的问题),但我相信这会影响性能,因为提高异常是非常昂贵的。在观看简单视频时,异常率约为1个异常/秒,但如果服务器有100个并发用户,则JVM可能会花费大量时间来计算堆栈跟踪而不是实际工作。

My problem is that for every terminated connection I get java.net.SocketException: Broken pipe exception. This not only pollutes the logs (which is a minor/solvable problem) but I believe this can hurt performance as raising exceptions is quite expensive. When watching simple video, the exception rate was around 1 exception/sec, but if the server had 100 concurrent users, then the JVM would probably be spending loads of time just calculating stack traces instead of doing real work.

我也使用iOS 6在iPhone上进行了测试,并且能够观察到与iPad 1相同的行为。重申一下,三星Android上的不会发生也不会我尝试过的任何桌面浏览器,包括桌面Mac上的Safari。

I have also tested this on iPhone using iOS 6 and was able to observe the same behaviour as iPad 1. Just to reiterate, this does not happen on Samsung Android nor any desktop browsers I have tried, including Safari on a desktop Mac.

问题:


  • 这是iPad / iPhone的已知错误/功能吗?

  • 有解决方法吗?

推荐答案

IIRC,断管只是意味着另一方在关闭其读取结束后收到数据。

IIRC, "broken pipe" simply means the other side received data after it closed its read end.

我能想到的最合理的事情是,它试图不浪费大量带宽下载永远不会被观看的视频(也许是他们已经与运营商达成一致,我怀疑这是背后的原因。直播限制

The most reasonable thing I can think of is that it's an attempt to not waste large amounts of bandwidth downloading video that never gets watched (perhaps something they've agreed with carriers, which I suspect is the reasoning behind the "live streaming" restriction:


超过10分钟的蜂窝网络上的视频流内容必须使用HTTP直播和包含一个基线64 kbps纯音频HTTP直播流。

"Video streaming content over a cellular network longer than 10 minutes must use HTTP Live Streaming and include a baseline 64 kbps audio-only HTTP Live stream."

唯一一个限制下载的简单方法是停止 read() ing并等待接收窗口填满,但这并不总是那么容易( NSURLConnection 真的没有让这很容易,例如)。

The only other easy way to throttle the download is to stop read()ing and wait for the receive window to fill up, but that's not always easy to do (NSURLConnection really doesn't make this easy, for example).

如果你非常幸运,客户端将关闭其写入结束(这样服务器将读取() EOF)并在关闭其读取结束前等待一会儿。在这种情况下,可能可以安全地假设客户端不再需要其余的下载。 RFC 2616 有点朦胧(似乎忘记了套接字只能在一个方向上关闭)但提到优雅的关闭(根据微软的说法涉及关闭写入端并从读取端完成读取,直到超时通过),但也说

If you're exceptionally lucky, the client will close its write end (such that the server will read() EOF) and wait for a little while before closing its read end. In this case, it might be safe to assume that the client no longer wants the rest of the download. RFC 2616 is a little hazy (it seems to forget that sockets can be closed in only one direction) but mentions "graceful close" (which according to Microsoft involves closing the write side and finishing reading from the read side until a timeout passes), but also says


服务器不应该在传输响应的过程中关闭连接,除非怀疑网络或客户端故障。

Servers SHOULD NOT close a connection in the middle of transmitting a response, unless a network or client failure is suspected.

所以如果你知道它是一个iDevice并且你读了EOF,那么服务器关闭套接字可能是安全的,前提是你已经彻底测试了它没有破坏任何东西&mdash ;改变HTTP行为取决于用户代理似乎是一个糟糕的主意。

So if you know it's an iDevice and you read EOF, then it might be safe for the server to close the socket, provided you've thoroughly tested that it doesn't break anything — changing HTTP behaviour depending on User-Agent just seems like a terrible idea.

或者,不要在意。你可以做U-A嗅探并忽略异常,如果它是一个iDevice(它似乎不如改变HTTP行为那么糟糕)。异常开销几乎可以忽略不计,并且可能远低于将其打印到日志的开销。每秒100个例外是没有的。如果您不确定,请对其进行分析。

Alternatively, don't care. You can do U-A sniffing and ignore the exception if it's an iDevice (which seems less terrible than changing HTTP behaviour). The exception overhead is almost certainly negligible, and probably far lower than the overhead of printing it to a log. 100 exceptions a second is nothing. Profile it if you're unsure.

您还可以提交文件苹果的错误,但随着这些事情的发展,它不是可疑的网络行为

You could also file a bug with Apple, but as these things go, it's not particularly dubious network behaviour.

这篇关于iPad / iPhone上的HTTP字节范围协议客户端行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆