轉自:
我觀察到,客戶端機器從單一服務器使用 HTTP 下載一個文件:
1. 單連接下載,速度沒有達到客戶端網絡的最大帶寬;
2. 多連接同時下載,傳輸速度有極大的提高,帶寬被占滿。
假設如下前提:
1. 服務器是單一的,沒有使用提供相同文件的其它服務器,也沒有使用同域名的其它服務器;
2. 服務器不對單個連接限速。
那么,是什么導致多連接下載的速度大為提高呢?換一種說法,是什么原因導致單一 TCP 連接沒有盡可能地利用帶寬呢?
是因為不同的 TCP 連接使用了不同的鏈路嗎?可是傳輸層不應該影響網絡層的吧?
是因為 TCP 本身的特性嗎?那又是怎樣的特性導致了這種結果呢?
測試結果:
1. 單連接下載:wget --header='Host: python.org' http://82.94.164.162/ftp/python/3.4.0/Python-3.4.0a3.tar.xz 138 KB/s
2. 多連接下載:aria2c -k 1M -x 16 -s 16 --header='Host: python.org' http://82.94.164.162/ftp/python/3.4.0/Python-3.4.0a3.tar.xz 414KiB/s
3. 國外服務器單連接下載: 2.26 MB/s
補充:文件是下載到內存的(tmpfs),因此避開了並發磁盤 I/O 帶來的影響。
=====================================================================================================================
作者:知乎用戶
鏈接:https://www.zhihu.com/question/21813579/answer/19402704
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
簡短版本:
TCP特性使得每個TCP連接可以得到均等的帶寬。在多用戶環境下,一個用戶擁有越多TCP連接,獲得的帶寬越大。
具體來說:
這個涉及到了TCP的擁塞控制。
我們先看一下單TCP連接的擁塞控制。
這是一個TCP連接的發送窗口。

綠色部分為發送者已發送,且接收者已確認(ACKed)。
黃色部分為發送者已發送,但接收者尚未確認("in-flight")。
藍色部分為可用但尚未發送。
灰色部分為不可用。
所以在RTT(round-trip time,來回通訊延遲)不變的情況下,cwnd這個變量基本決定傳輸速率。
發送者總會試圖找到不丟包情況下的最大速率。按照TCP協議,在傳輸開始之后,每接收到一個確認(ACK)就會把cwnd這個變量增大一倍。所以TCP連接開始之后應該是這個樣子。
剛開始的時候傳輸速率應該是指數被增長的,直到丟包發生。丟包會有兩種情況:
1.當接收者發送給發送者的ACK丟失了,這時會觸發超時(timeout)。
2.當發送者發送給接收者的數據包丟失了,發送者會收到接收者發來的重復ACK,如果發送者收到了3個重復的ACK,也會認為發生了丟包。
具體對這兩種情況采取的措施略有不同,但粗略來說,變量cwnd會被減半,也就是說傳輸速率減半。然后cwnd會再次增大,直到下次丟包發生。所以忽略最開始,TCP的吞吐量應該是這樣。

好,那么現在我們來看多TCP連接的擁塞控制。
我們假設有兩條同樣的TCP連接。在他們的連接中間有一個共用的瓶頸路由器,帶寬為R。
假設這兩條連接都需要傳輸足夠大量的數據,那么不論他們誰先開始傳輸,最后一定會均分帶寬。
因為如果總傳輸速率低於R的時候就會不斷增大傳輸速率,某個連接在增大傳輸速率的時候發生丟包就會減半傳輸速率,最后趨於平衡。
所以k條經過同一節點TCP連接會平分帶寬R,每條連接得到帶寬R/k。
正因為如此,不論是以前的net vampire,還是現在的迅雷都采取增加並發連接數的方法來加快下載速度。
references: