0

假设我想使用范围标头在支持分段下载的 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 的冗余字节。

  1. 所以对于 t1,有没有办法告诉服务器,“好的计划改变了,我只需要 1599,所以在你发送 1599 时停止,不要从 1600 发送字节”?我能想出的一个“解决方法”是让 t1 丢弃从字节 1600 到 1999 的任何字节,但是这些字节仍然通过网络传递,所以它们仍然消耗带宽并影响网络吞吐量,这不是什么我想要...我正在尝试设计一个动态分段方案来提高下载速度,所以这就是我在这里关心速度和吞吐量的原因。我想如果它是一个大文件,比如 1GB,并且使用两个线程,那么在最坏的情况下,我必须丢弃的冗余字节大约是 1GB,这很多......一个人提到简单地终止联系。我想知道,当服务器听到我的连接关闭请求时,服务器是否会立即停止在请求的范围内发送任何未发送的字节,例如字节 1678、1830 等。---我知道在服务器实际听到连接关闭请求之前,它可能仍会发送几个冗余字节;不过,丢弃那么多字节并不是一个大问题。

  2. 除了我到目前为止的方法之外,还有其他方法可以使动态分割起作用吗?

  3. 在上面的场景中,当 t2 从 2000 到 3999 完成它的工作并且即将从 1600 到 1999 抓取字节时,t2 会默认使用相同的 http 连接来抓取新的字节范围还是我应该事先做一些事情(例如,发送额外的GET消息等​​的参数)来实现它?我是对的,在这种情况下,使用相同的连接比关闭和打开另一个连接更好吗?

我是用 clojure 写的,所以如果你有 java 或 clojure 中的任何代码示例,那将非常有帮助。:-)

4

1 回答 1

0

所以想象一下,你想下载一个 4M 的文件,并希望两个线程来完成它。让第一个线程从 0 到中间,第二个线程从末端到中间字节不是很好吗?这是看到这个问题时首先想到的。

由于您可以请求范围,因此您可以在足够多时终止连接,也可以分块工作。一个 4MB 的文件将由 1024 个 4k 块组成。两个线程从任一侧获取块,当你得到这 1024 个块时你停止,而不关心哪个线程得到更多。

但这实际上只是视觉上的愉悦。如果您有 n 个块的计数器 c,您可以使用它来拥有多个线程,具体取决于下载的大小和线程的最大限制。所有人都可以通过递增计数器并将其存储为工作来获取第一个空闲块。如果发生某些事情,您需要确保线程工作完成。除此之外,当计数器达到 n 并且所有线程都完成时,您将完成。

我在考虑 bitset,但我认为您可以通过了解每个线程和该计数器的当前工作来进行足够的控制。确保增加它的方法是同步的。

于 2013-08-22T22:31:50.880 回答