当前位置: 首页 > 编程日记 > 正文

为什么多 TCP 连接比单 TCP 连接传输快

转自:

我观察到,客户端机器从单一服务器使用 HTTP 下载一个文件:
1. 单连接下载,速度没有达到客户端网络的最大带宽;
2. 多连接同时下载,传输速度有极大的提高,带宽被占满。

假设如下前提:
1. 服务器是单一的,没有使用提供相同文件的其它服务器,也没有使用同域名的其它服务器;
2. 服务器不对单个连接限速。

那么,是什么导致多连接下载的速度大为提高呢?换一种说法,是什么原因导致单一 TCP 连接没有尽可能地利用带宽呢?
是因为不同的 TCP 连接使用了不同的链路吗?可是传输层不应该影响网络层的吧?
是因为 TCP 本身的特性吗?那又是怎样的特性导致了这种结果呢?

测试结果:
1. 单连接下载:wget --header='Host: python.org' 138 KB/s
2. 多连接下载:aria2c -k 1M -x 16 -s 16 --header='Host: python.org' 414KiB/s
3. 国外服务器单连接下载: 2.26 MB/s

补充:文件是下载到内存的(tmpfs),因此避开了并发磁盘 I/O 带来的影响。

=====================================================================================================================

作者:知乎用户
链接:https://www.zhihu.com/question/21813579/answer/19402704
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

简短版本:

TCP特性使得每个TCP连接可以得到均等的带宽。在多用户环境下,一个用户拥有越多TCP连接,获得的带宽越大。

具体来说:

这个涉及到了TCP的拥塞控制。

我们先看一下单TCP连接的拥塞控制。

这是一个TCP连接的发送窗口。
<img src="https://pic3.zhimg.com/ac38d18e3cd9c7941bbd753fe37bbbba_b.jpg" data-rawwidth="434" data-rawheight="309" class="origin_image zh-lightbox-thumb" width="434" data-original="https://pic3.zhimg.com/ac38d18e3cd9c7941bbd753fe37bbbba_r.jpg">

绿色部分为发送者已发送,且接收者已确认(ACKed)。
黄色部分为发送者已发送,但接收者尚未确认("in-flight")。
蓝色部分为可用但尚未发送。
灰色部分为不可用。

所以在RTT(round-trip time,来回通讯延迟)不变的情况下,cwnd这个变量基本决定传输速率。
<img src="https://pic3.zhimg.com/382de3cc7379025d169f7e3264368252_b.jpg" data-rawwidth="401" data-rawheight="105" class="content_image" width="401">发送者总会试图找到不丢包情况下的最大速率。按照TCP协议,在传输开始之后,每接收到一个确认(ACK)就会把cwnd这个变量增大一倍。所以TCP连接开始之后应该是这个样子。发送者总会试图找到不丢包情况下的最大速率。按照TCP协议,在传输开始之后,每接收到一个确认(ACK)就会把cwnd这个变量增大一倍。所以TCP连接开始之后应该是这个样子。
<img src="https://pic2.zhimg.com/d6eceab08d6e7e33b62f918502c2558d_b.jpg" data-rawwidth="519" data-rawheight="508" class="origin_image zh-lightbox-thumb" width="519" data-original="https://pic2.zhimg.com/d6eceab08d6e7e33b62f918502c2558d_r.jpg">刚开始的时候传输速率应该是指数被增长的,直到丢包发生。丢包会有两种情况:

刚开始的时候传输速率应该是指数被增长的,直到丢包发生。丢包会有两种情况:
1.当接收者发送给发送者的ACK丢失了,这时会触发超时(timeout)。
2.当发送者发送给接收者的数据包丢失了,发送者会收到接收者发来的重复ACK,如果发送者收到了3个重复的ACK,也会认为发生了丢包。

具体对这两种情况采取的措施略有不同,但粗略来说,变量cwnd会被减半,也就是说传输速率减半。然后cwnd会再次增大,直到下次丢包发生。所以忽略最开始,TCP的吞吐量应该是这样。
<img src="https://pic2.zhimg.com/931df6c47759a69e63cfd37c82594b21_b.jpg" data-rawwidth="663" data-rawheight="329" class="origin_image zh-lightbox-thumb" width="663" data-original="https://pic2.zhimg.com/931df6c47759a69e63cfd37c82594b21_r.jpg">
好,那么现在我们来看多TCP连接的拥塞控制。
我们假设有两条同样的TCP连接。在他们的连接中间有一个共用的瓶颈路由器,带宽为R。
<img src="https://pic3.zhimg.com/91b2492e537591557e5009f814aefef2_b.jpg" data-rawwidth="807" data-rawheight="410" class="origin_image zh-lightbox-thumb" width="807" data-original="https://pic3.zhimg.com/91b2492e537591557e5009f814aefef2_r.jpg">假设这两条连接都需要传输足够大量的数据,那么不论他们谁先开始传输,最后一定会均分带宽。假设这两条连接都需要传输足够大量的数据,那么不论他们谁先开始传输,最后一定会均分带宽。
<img src="https://pic4.zhimg.com/6dab723d3bbdffb03c748a1b69bba2df_b.jpg" data-rawwidth="853" data-rawheight="489" class="origin_image zh-lightbox-thumb" width="853" data-original="https://pic4.zhimg.com/6dab723d3bbdffb03c748a1b69bba2df_r.jpg">因为如果总传输速率低于R的时候就会不断增大传输速率,某个连接在增大传输速率的时候发生丢包就会减半传输速率,最后趋于平衡。

因为如果总传输速率低于R的时候就会不断增大传输速率,某个连接在增大传输速率的时候发生丢包就会减半传输速率,最后趋于平衡。

所以k条经过同一节点TCP连接会平分带宽R,每条连接得到带宽R/k。

正因为如此,不论是以前的net vampire,还是现在的迅雷都采取增加并发连接数的方法来加快下载速度。

references:
  • James F. Kurose, Keith W. Ross: Computer Networking: A Top-Down Approach

转载于:https://www.cnblogs.com/leonxyzh/p/7446458.html

相关文章:

学Python的好处有哪些?

Python是一种比较简单的编程语言技术,想要快速进入到IT行业,Python是非常好的选择,为什么这么说呢?下面小编就为大家详细的介绍一下学Python的好处有哪些? ​  学Python的好处有哪些? 1.如果你是一名新媒体相关人员,学习Pyth…

技术图文:如何利用C# 实现 Kruskal 最小生成树算法?

背景 以前我写过一些图文来介绍有关数据结构与算法的知识: 8大排序算法之:直接插入排序(Straight Insertion Sort)8大排序算法之:希尔插入排序(Shell Insertion Sort)8大排序算法之&#xff1…

又偷懒了4个月,督促自己

又偷懒了4个月 每天浑浑噩噩,做着无聊简单的体力活,我不应该是这个追求撒!~~ 爸爸说的对,无论怎么样自己都要独立,要学习,爸爸希望我还去继续学习会计,我看下半年吧,各种学习都要&am…

java.lang.NoSuchMethodError: org.springframework.web.context.support.XmlWebApplicationContext.getEnv

转自:https://blog.csdn.net/u012941811/article/details/16960493 ava.lang.NoSuchMethodError: org.springframework.web.context.support.XmlWebApplicationContext.getEnvironment()Lorg/springframework/core/env/ConfigurableEnvironment; at 缺 org.springf…

零基础可以学好UI设计吗

随着UI设计行业的不断扩大发展,很多人都想要学习UI设计技术,但有很多同学都是零基础,想知道零基础可以学好UI设计吗?我们来看看下面的详细介绍就知道了。 零基础可以学好UI设计吗? 如果零基础自己学习UI设计着实有点吃力,毕竟对…

技术图文:如何利用C# 实现 Prim 最小生成树算法?

背景 我们上一篇图文介绍了 如何利用 C# 实现 Kruskal 最小生成树算法?,Kruskal 算法通过寻找边最优的方式来构造最小生成树,本篇图文介绍如何利用 C# 实现 Prim 最小生成树算法,Prim 算法通过寻找顶点最优的方式来构造最小生成树…

去除iphone图标的半弧高亮效果

只需要在info.plist里面添加一条记录UIPrerenderedIcon 新版的XCODE 会自动识别为Icon already includes gloss effects 打上勾就OK了 如果没有识别的右边栏写上YES就可以。转载于:https://www.cnblogs.com/jiewong/archive/2011/01/14/1935718.html

【短视频SDK - 参数解析】对焦模式、裁剪模式、视频质量、分辨率、视频比例、帧率、关键帧间隔等参数解析...

1.参数简析 参数名称简介影响裁剪模式分为填充模式和裁剪模式影响图像画面的展示细节视频质量是指生成的视频的输出参数,是一组参数决定的数值视频清晰度和文件大小分辨率图像分辨率则是单位英寸中所包含的像素点数,分辨率影响图像大小,与图像…

21年最新Python面试题及答案汇总详解(上)

错过三月找工作的机会,还要错过四月的好时期吗?Python面试你做准备了吗?下面小编整理了一套2021年最新Python常见面试题目,及Python面试题目答案汇总。希望能够帮助到大家。 21年最新Python面试题及答案汇总详解(上) 1、列表(list)和元组(tuple)有什么…

sina微博api源码阅读之函数

1. array_map将类的静态成员函数作为回调函数用在指定的单元上,可以递归调用 public static function urlencode_rfc3986($input) { if (is_array($input)) { return array_map(array(OAuthUtil, urlencode_rfc3986), $input); } else …

LeetCode实战:将有序数组转换为二叉搜索树

题目英文 Given an array where elements are sorted in ascending order, convert it to a height balanced BST. For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by mo…

Spring、Spring Boot和TestNG测试指南 - @ActiveProfiles

Github地址 ActiveProfiles可以用来在测试的时候启用某些Profile的Bean。本章节的测试代码使用了下面的这个配置: Configuration public class Config {BeanProfile("dev")public Foo fooDev() {return new Foo("dev");}BeanProfile("prod…

python语言中如何使用注释

每一种计算机语言都有自己的注释方式,我们知道注释的作用是解释这些代码,方便程序员以后的检查和修改。而且注释的一部分在运行程序的过程中不起作用,也不会显示出来。下面我们将为大家介绍,在python语言中如何使用注释? 在pytho…

RHEL5(CentOS)下nginx+php+mysql+tomcat+memchached配置全过程(转)

RHEL5(CentOS)下nginxphpmysqltomcatmemchached配置全过程 一、准备工作: SSH,telnet终端中文显示乱码解决办法 vi /etc/sysconfig/i18n将内容改为 LANG"zh_CN.GB18030" LANGUAGE"zh_CN.GB18030:zh_CN.GB2312:zh_CN" SUPPORTED"zh_CN.GB18…

LeetCode实战:搜索二维矩阵

题目英文 Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: Integers in each row are sorted from left to right.The first integer of each row is greater than the last integer of the previou…

windows指令

为什么80%的码农都做不了架构师?>>> C:\Windows\System32\drivers\etc nbtstat -a 1.7.2.2s 检查该IP的主机名称 WExNmU5Z windows启动配置界面 在“运行”中输入“msconfig mstsc -admin 远程 虚拟机的判断:如果有vmtoolsd.exe进程就是虚拟…

Java培训好不好?零基础可以学吗?

5g时代的来临,越来越多的人开启智能时代,互联网行业的发展速度越来越快,高薪行业一直受到很多人的关注,尤其是java这一块,很多人都想学习,那么参加Java培训好不好?零基础可以学吗? Java培训好不好?零基础…

顺水行舟,逆水行舟

水,或温柔,或猛烈 万物皆可比喻为水 顺水行舟,逆水行舟,皆为操船者智慧之体现 翻船者。。。把船搞翻了几回还执意而为,SB也。。。转载于:https://www.cnblogs.com/Zetazzz/archive/2011/01/30/1948082.html

LeetCode实战:二叉树的最大深度

题目英文 Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. Note: A leaf is a node with no children. Example: Given binary tree [3,9,20,null,n…

jfinal整合shiro回顾

2019独角兽企业重金招聘Python工程师标准>>> 目前jfinal使用shiro进行身份验证和授权的后台实现已完成,现在我再来总结下学习过程及代码实现过程。最近半年多项目开发都用.net,但又不甘心用了一年多的java,jfinal就这样被废弃&…

零基础学习Java培训有什么攻略

零基础学习Java培训有什么攻略?java是主流编程语言之一,我们在学习Java的时候需要制定Java学习路线图,Java涉及到的知识点非常的多,我们该从何学起呢?怎么系统的学习呢?来看看下面的详细介绍。 一、Java学习阶段 将Java学习过程分为3个阶段…

php去掉字符串的最后一个字符 substr()的用法

今天项目中用到,去掉字符串中的最后一个字符原字符串1,2,3,4,5,6,去掉最后一个字符",",最终结果为1,2,3,4,5,6代码如下:$str "1,2,3,4,5,6,"; $newstr substr($str,0,strlen($str)-1);echo $newstr;系统自带的函数也可…

如何加入LSGO软件技术团队?

背景 马上就要放暑假了! LSGO软件技术团队 也要开始招新了! 本次招入的同学,我会亲自来带,和你一起学习,共同成长。 我们的主要研究方向是机器学习,再详细一些就是视觉、自然语言处理和量化金融。 以下是…

《MySQL技术内幕:InnoDB存储引擎》读书笔记

2019独角兽企业重金招聘Python工程师标准>>> 1.InnoDB中每一页的大小默认为16kb,但是其也支持压缩页的功能,即将原本16kb的页压缩为1kb、2kb、4kb和8kb。当需要从缓存池中申请4kb大小的页时,MySQL的申请步骤如下: 检查…

UI设计要做什么,UI设计培训都要学什么

UI设计要做什么,UI设计培训都要学什么?相信有很多人都对这个问题比较感兴趣,近几年,UI设计被越来越多的人关注,行业薪资水平也是一路飙升,很多人都在准备学习UI设计,那么具体的内容,下面我们来…

[置顶] 如何搭建一个 Data Guard 环境

在Blog里零零散散的讲了一些DB 维护的东西,比较杂,也比较散。 这里就Oracle Data Guard 这块做一个小结。 主要是流程上的东西。 做个参考,以后装DG,照这个流程走就ok了。 一. 服务器设置1.1 硬盘的规划根据自己的业务量来规划硬…

技术图文:如何进行代码的重构?以封装 BigOne API 为例

背景 自从把“量化交易”作为自己精进的技术方向之后,我做了一些准备工作。 比如: 1. 爬取交易所的公告,根据公告的信息来研判数字货币的短期走势。 这里面有一个“流动性溢价”的概念,等后面我会结合一些例子跟大家聊聊这块的…

《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一3.7.5 使用StAX写出XML文档

3.7.5 使用StAX写出XML文档 在前一节中,你看到了如何通过写出DOM树的方法来产生XML文件。如果这个DOM树没有其他任何用途,那么这种方式就不是很高效。StAX API使我们可以直接将XML树写出,这需要从某个OutputStream中构建一个XMLStreamWriter…

大数据就业前景怎么样?需要学会哪些技术?

智能时代的来临,我们日常生活中的很多技术都可以用大数据来实现,大数据开发行业做为IT行业中的一类更是前景无限。所以很多人想转行做大数据开发。那么现在大数据就业前景怎么样?需要学会哪些技术? 大数据就业前景怎么样?需要学会哪些技术?大数据行业…

技术图文:如何利用 C# 实现 误差反向传播 学习规则?

背景 我们在 如何利用 C# 对神经网络模型进行抽象? 中完成了神经网络的抽象结构: 三个接口:激活函数、有监督学习、无监督学习 三个抽象类:神经元、网络层、网络拓扑 我们在 如何利用 C# 实现神经网络的感知器模型? …