2012-06-13 34 views
6

我正在使用codeplex 1.1版中的c# webserver。我已经实现了Accept-Range头文件,它确实有效。然而,当我使用Wireshark(版本1.4.1(SVN版本34476从/trunk-1.4))来捕捉流量,我看到以下内容:Http range header请求整个文件

GET /movies/i_am_legend%20dvd/main.m4v HTTP/1.1 
Host: 10.100.1.199:8081 
Accept: */* 
Range: bytes=0-1 
Accept-Encoding: identity 
Connection: keep-alive 
User-Agent: AppleCoreMedia/1.0.0.9B206 (iPad; U; CPU OS 5_1_1 like Mac OS X; nl_nl) 
X-Playback-Session-Id: 9CED81CC-BFAE-4CF6-A477-0EA62B2C652F 

HTTP/1.1 206 PartialContent 
Content-Range: bytes 0-1/652965648 
Accept-Ranges: bytes 
ETag: "0daA8D4/wgt4MFvxdNIPLw==" 
Date: Wed, 13 Jun 2012 09:10:18 GMT 
Content-Length: 2 
Content-Type: video/x-m4v 
Server: Tiny WebServer 
Connection: keep-alive 

.. << 2 bytes data 

GET /movies/i_am_legend%20dvd/main.m4v HTTP/1.1 
Host: 10.100.1.199:8081 
Accept: */* 
Range: bytes=0-652965647 
Accept-Encoding: identity 
Connection: keep-alive 
User-Agent: AppleCoreMedia/1.0.0.9B206 (iPad; U; CPU OS 5_1_1 like Mac OS X; nl_nl) 
X-Playback-Session-Id: 9CED81CC-BFAE-4CF6-A477-0EA62B2C652F 

HTTP/1.1 206 PartialContent 
Content-Range: bytes 0-652965647/652965648 
Accept-Ranges: bytes 
ETag: "0daA8D4/wgt4MFvxdNIPLw==" 
Date: Wed, 13 Jun 2012 09:10:18 GMT 
Content-Length: 652965648 
Content-Type: video/x-m4v 
Server: Tiny WebServer 
Connection: keep-alive 

的Web服务器将尝试发送整个文件(> 600MB ),wireshark显示整个对话是159774字节。如果我做同样的事情与IIS出现了类似头

GET /ipod/main.m4v HTTP/1.1 
Host: 10.100.1.199 
User-Agent: AppleCoreMedia/1.0.0.9B206 (iPad; U; CPU OS 5_1_1 like Mac OS X; nl_nl) 
Accept: */* 
Range: bytes=0-1 
Accept-Encoding: identity 
X-Playback-Session-Id: C5BBF91D-78AB-42BA-ACE0-D74AB9D845CE 
Connection: keep-alive 

HTTP/1.1 206 Partial Content 
Content-Type: video/x-m4v 
Last-Modified: Mon, 11 Jun 2012 10:33:41 GMT 
Accept-Ranges: bytes 
ETag: "7243cabbd47cd1:0" 
Server: Microsoft-IIS/7.5 
X-Powered-By: ASP.NET 
Date: Wed, 13 Jun 2012 09:21:03 GMT 
Content-Length: 2 
Content-Range: bytes 0-1/652965648 

.. << 2 bytes of data 

GET /ipod/main.m4v HTTP/1.1 
Host: 10.100.1.199 
User-Agent: AppleCoreMedia/1.0.0.9B206 (iPad; U; CPU OS 5_1_1 like Mac OS X; nl_nl) 
Accept: */* 
Range: bytes=0-652965647 
Accept-Encoding: identity 
X-Playback-Session-Id: C5BBF91D-78AB-42BA-ACE0-D74AB9D845CE 
Connection: keep-alive 

HTTP/1.1 206 Partial Content 
Content-Type: video/x-m4v 
Last-Modified: Mon, 11 Jun 2012 10:33:41 GMT 
Accept-Ranges: bytes 
ETag: "7243cabbd47cd1:0" 
Server: Microsoft-IIS/7.5 
X-Powered-By: ASP.NET 
Date: Wed, 13 Jun 2012 09:21:03 GMT 
Content-Length: 652965648 
Content-Range: bytes 0-652965647/652965648 

Wireshark的显示,整个对话是175615个字节。

...我已经寻找更多信息的Accept-范围头,到目前为止,我只能找到服务器必须发送请求的范围。但我不能相信这是为了一次使用范围请求来请求一个巨大的文件。

我的网络服务器试图发送整个文件,因为它已被请求,但我看到新的范围请求进来这样更大的范围(只有范围头从请求头复制。 ..)是Wireshark

Range: bytes=2162688-652965647 (@ time == 1.646204) 
Range: bytes=4980736-652965647 (@ time == 2.754322) 
Range: bytes=6356992-652965647 (@ time == 2.922479) 

this我曾尝试完毕后发送一个较短的范围内,每当我得到整个文件的范围请求的时间。但后来它不会在所有的工作。

我想知道:

  1. 是整个文件的范围要求是某种iOS中的bug(4.3.3带有看到它为好)我本来期望Range: bytes=0-1和重播像Range: bytes=0-65535/652965648
  2. 后我可以采用某种优雅地否认这一点大请求并告诉我的要求,我可以一次提供最大尺寸? (我没有在RFC中找到这个)
  3. IIS是否在一定数量的字节之后简单地中止这个请求?

编辑:对于编号3:不是IIS,但浏览器似乎只是简单地中止(和关闭)连接。之后提出新的请求。我无法想象范围请求是为了请求整个文件或文件的巨大部分。

编辑:在iOS7它似乎已经改变了。第一个范围请求仍然是相同的(字节0-1)。之后,我会看到上面提到的2或3个范围请求,其中最后一个请求持续传输较长时间的字节。但是仍然有多个请求完成。

+2

我[观察类似的行为](http://stackoverflow.com/questions/12637728/http-byte-range-protocol-client-behaviour-on-ipad-iphone),对我来说,它看起来像这样iPad/iPhone问题。 – mindas

+0

@mindas确实是你;重新面对同样的事情。由于我使用的网络服务器的结构,我没有多少选择,需要重新抛出异常来停止处理范围请求。幸运的是,我只有1个客户端连接在同一时间(但它也适用于2或3)。我希望你会得到一些有用的答案。 –

+1

我们在测试中看到的是safari询问前两个字节(范围0-1),然后它要求整个文件并立即关闭连接,然后它要求*最后几百KB文件*(我怀疑它包含重要的元数据,Chrome会按照这种方式做同样的事情),然后开始以小块开始请求文件。我怀疑确切的模式会因视频格式而异。 –

回答

3
  1. 是整个文件的范围要求是在iOS的某种错误的(与4.3.3看到它)我本来期望范围:字节= 0-1和重播像后范围:bytes = 0-65535/652965648

我不知道它是否是一个bug。但是,我可以想到媒体播放器在一个请求中请求整个文件的原因。通过这种方式,媒体播放器获得数据流,从中可以从头到尾读取所有数据。

只要媒体播放器从流中读取足够的数据,它就可以开始播放媒体文件。然后它选择在媒体播放时应该在背景中缓冲多少数据。可能有几种不同的方法:

  • 急切缓冲整个媒体文件。当带宽很便宜时(用户不付费或为数据传输支付统一费率),这是一个很好的策略。假定用户将希望看到/收听整个媒体文件。

  • 懒惰的缓冲只是为了避免滞后。当带宽昂贵时(用户按字节支付),这是一个很好的策略。

    在理想的设置中,媒体播放器不需要缓冲任何东西,而是实时播放媒体时解码数据流。但是,这将要求底层网络频道将保持超级稳定,并始终以所需的速度传输数据。

    事实并非如此,因此媒体播放器会选择缓冲几秒钟或几分钟。

需要注意的是无论选择何种策略,它仍然是有意义的媒体播放器来请求整个资源在单个请求中是很重要的。

然而,范围请求是当媒体播放器重要:

  • 的连接被中断(因任何原因)。
  • 用户在媒体中跳跃前进。 (例如,想要看什么是电影中的10分钟)

媒体播放器然后可以关闭它最初打开的数据流并发送所需位置的范围请求。

  • 我可以采用某种优雅地否认这个大的请求,并告知要求,我可以一次提供一个最大尺寸是多少?
  • 不,你不能。范围请求由客户端/浏览器和已声明其支持范围请求(通过Accept-Ranges标头)的服务器发起,必须服从客户端并以其请求的任何范围做出响应。

    但是,您可以做的是使用Transfer-Encoding: chunked标头发送数据。这将使你的服务器能够控制它应该传输多大的数据块。但是,它仍然通过单个HTTP连接完成。

    +1

    感谢广泛的反应。我会将其标记为答案。 –