我的服务器上有一个大文件。我发现多线程下载可以达到 20Mbs,但单线程可以达到 10Mbps,有人能解释一下吗?
答案1
通常这是因为您与其他服务器之间某处有防火墙,将每个 HTTP 流限制为 10Mbps。使用多线程时,您将获得 2x 10Mb(每个线程一个)。
答案2
当“保持管道充满”时,TCP 工作效果最佳 - 当发送应用程序保持足够快地发送缓冲区以保持发送方 TCP 堆栈不断供应数据,以便它始终可以在网络上“传输”数据,并且当接收方应用程序保持足够快地从接收方 TCP 堆栈读取数据,以便接收方 TCP 窗口永远不会填满(再次,因此发送 TCP 堆栈可以始终保持数据在网络上“传输”)。
我可以想象一个编写不佳的单线程发送方应用程序将一个缓冲区传递给 TCP 堆栈,等待听到它已被完全确认,然后传递另一个缓冲区。这意味着一旦第一个缓冲区的末尾在网络上“飞行”,发送 TCP 堆栈就会缺乏要发送的数据,这意味着管道耗尽并且直到确认返回并且发送应用程序向其传递新缓冲区后才会重新填充。
我还可以想象一个编写不佳的单线程接收方应用程序无法足够快地从接收方 TCP 堆栈读取数据,从而导致 TCP 堆栈的缓冲区填满,这意味着 TCP 窗口填满,这会导致发送方 TCP 堆栈停止发送,直到窗口打开一些。增加接收方的 TCP 窗口大小可能会有所帮助,但真正的解决方案是更快地读取数据。
答案3
这是由于您与服务器之间的 ping 以及下载软件使用的数据包大小/tcpip 窗口大小所致。
基本上,如果您对服务器的 ping 时间为 100ms,并且请求 100kb 的数据包,则即使您的互联网速度无限,您也只能使用 1 个连接每秒获得 10 个数据包。
答案4
嗯,这可能是因为您只能通过一个连接传输这么多数据。然而,在多线程程序中,您可以让两个连接同时接收数据,从而使您可以获得的信息量翻倍。这有一些限制,例如您正在从中下载的服务器的速度......向编写多线程下载程序的人致敬,这些并不容易编写。