我正在测试支持HTTP byte range requests的HTTP servlet implementation (kindly shared by BalusC)。iPad/iPhone上的HTTP字节范围协议客户端行为
我发现了不同的HTTP客户端之间的一些特殊的区别,并想知道我是否没有丢失任何东西。我为我的测试使用了> 2G mp4视频文件,并使用Wireshark捕获数据包。这大概会发生什么:
三星Galaxy SII:
- HTTP GET文件请求到来时,要求字节范围
[0; <almost the end of the file>]
- 服务器响应,开始流的文件
每个后续块在相同的HTTP响应的范围内服务。没有新的HTTP请求被发送(除非视频被快速转发到某个位置)。该流的代码块是非常简单,它读取
RandomAccessFile input
,并通过byte[] buffer
写入OutputStream output
:while ((read = input.read(buffer)) > 0) { output.write(buffer, 0, read); }
- HTTP GET文件请求到来时,要求字节范围
- 的iPad 1
- HTTP GET请求文件来,要求字节范围
[0; <almost the end of the file>]
- 服务器响应,开始流式传输文件
- iPad获取一个或两个数据块,然后单方面决定停止接受来自服务器的字节并发出单独的
GET
要求为下一个文件块。新的范围边界例如[100, almost the end of the file]
。视频显示OK。 - 循环再次从步骤2开始重复。左边界始终移向文件末尾。
- HTTP GET请求文件来,要求字节范围
我没有调查的连接究竟如何终止。这可能是iPad停止发送TCP ACK数据包,我想这并不重要。
我的问题是,对于每个终止连接,我得到java.net.SocketException: Broken pipe
异常。这不仅污染日志(这是一个次要的/可解决的问题),但我相信这可能会损害性能,因为引发异常是非常昂贵的。在观看简单的视频时,异常速率大约为1次异常/秒,但是如果服务器有100个并发用户,那么JVM可能花费大量时间来计算堆栈跟踪,而不是进行实际工作。
我一直使用的是iOS 6还测试了这款iPhone和能够观察到相同的行为像iPad 1.刚重申,这一不会对三星的Android也没有任何桌面浏览器我都试过了,包括Safari上发生桌面Mac。
问题:
- 这是iPad/iPhone的的知道是不是BUG /功能?
- 有没有解决这个问题的方法?
找到[由别人问的同一问题](https://groups.google.com/forum/#!msg/youtube-api-gdata/V6RU2h9afBg/ibaJ7yOHjBAJ)以及[另一个](http://stackoverflow.com/questions/6094556/mobile-safari-makes-multiple-video-requests),遗憾的是到目前为止没有有用的答案:( – mindas