假设我想使用范围标头在支持分段下载的 http 服务器上下载文件。例如:
- 文件网址:www.music.com/rock.mp3
- 文件长度:4000 字节
假设我启动了两个线程,每个线程都在下载一半字节的文件。
- 线程 t1 下载从 0 到 1999 的字节
- 线程 t2 从 2000 下载字节到 3999
假设t2下载完后半部分,t1只下载了1199字节,所以t1还有1200到1999字节要走,总共800字节。
现在我让 t2 开始从字节 1600 下载到字节 1999,并且我希望 t1 继续下载到字节 1599。我认为用 t2 这样做没有问题,我只需要发送另一个范围从 1600 到 1999 的 get 消息。但是t1 最初从 0 到 1999 范围内发送 get 消息,而不是从 0 到 1599,因此服务器将继续向 t1 发送字节,直到发送了 1999 字节,从 t1 的角度来看,这包括从 1600 到 1999 的冗余字节。
所以对于 t1,有没有办法告诉服务器,“好的计划改变了,我只需要 1599,所以在你发送 1599 时停止,不要从 1600 发送字节”?我能想出的一个“解决方法”是让 t1 丢弃从字节 1600 到 1999 的任何字节,但是这些字节仍然通过网络传递,所以它们仍然消耗带宽并影响网络吞吐量,这不是什么我想要...我正在尝试设计一个动态分段方案来提高下载速度,所以这就是我在这里关心速度和吞吐量的原因。我想如果它是一个大文件,比如 1GB,并且使用两个线程,那么在最坏的情况下,我必须丢弃的冗余字节大约是 1GB,这很多......一个人提到简单地终止联系。我想知道,当服务器听到我的连接关闭请求时,服务器是否会立即停止在请求的范围内发送任何未发送的字节,例如字节 1678、1830 等。---我知道在服务器实际听到连接关闭请求之前,它可能仍会发送几个冗余字节;不过,丢弃那么多字节并不是一个大问题。
除了我到目前为止的方法之外,还有其他方法可以使动态分割起作用吗?
在上面的场景中,当 t2 从 2000 到 3999 完成它的工作并且即将从 1600 到 1999 抓取字节时,t2 会默认使用相同的 http 连接来抓取新的字节范围还是我应该事先做一些事情(例如,发送额外的GET消息等的参数)来实现它?我是对的,在这种情况下,使用相同的连接比关闭和打开另一个连接更好吗?
我是用 clojure 写的,所以如果你有 java 或 clojure 中的任何代码示例,那将非常有帮助。:-)