假设一个办公室里的人希望将 HTTP 下载限制为其互联网连接速度的最大带宽 40%,以免阻塞其他流量。
我们说“您的防火墙不支持它”,他们就会说出那句不可避免的话“我们以前可以用我们的 Netgear/DLink/DrayTek 来做到这一点”。
想想看,一次下载是这样的:
HTTP GET request
Server sends file data as TCP packets
Client acknowledges receipt of TCP packets
Repeat until download finished.
速度取决于服务器向您发送数据的速度以及您确认数据的速度。
因此,要限制下载速度,您有两种选择:
1)指示服务器以更慢的速度向您发送数据 - 我认为 TCP 或 HTTP 中没有任何协议功能可以请求这样做。
2)通过限制上传速度来更慢地确认数据包,同时也会破坏您的上传速度。
设备如何实现这种限制?有标准方法吗?
答案1
TCP 本身实现了拥塞控制。
这些速率限制器只会丢弃超过限制的数据包。TCP 会处理此问题,确保所有数据包都按顺序到达;客户端不会对丢弃的数据包进行 ACK,服务器会重新发送这些数据包。
服务器的 TCP 堆栈将重新发送数据包,并且还会稍微降低发送速率,因为它认为它与客户端之间出现拥塞。它会重新加速,直到速率限制器再次丢弃数据包,依此类推。
答案2
我听过的关于 TCP 固有节流方法的最好描述来自最近的一篇现在安全播客引用史蒂夫·吉布森的话:
因此,根据普遍共识,TCP 是一种非常聪明的协议,它执行一种称为“慢启动”的操作。它通常被允许发送一定数量的数据包而无需确认。因此,我们的想法是,让我们开始吧。通常这个数字是两个。因此,当 TCP 启动时,它可以一个接一个地发送两个数据包。如果第一个数据包没有得到确认,它将发送第二个数据包。但随后它会等待。然后,节流规则是,我们允许每收到一个确认,未确认的数据包数量就增加一个。
让我们考虑一下。我们允许每收到一个确认,未确认数据包的数量就增加一个。因此,我们首先发送两个数据包作为我们商定的开始。它们得到确认。因此,我们有了第一个确认。我们允许自己发送两个。现在,在收到第一个确认后,我们将确认数量增加一到三个。因此,我们现在可以发送另外三个数据包而无需进一步确认。当我们之前发送的任何内容收到确认时,我们将确认数量增加到四个。这被称为“拥塞窗口”。它不是在线路上发送的窗口,也就是说,它不像接收窗口,接收窗口是 TCP 报头的 16 位,告诉我们能够提前发送多少数据。这是一个窗口。它基本上是 TCP 堆栈为避免连接而维护的一个计数器,其想法是,在某个时候它会中断。
如果我们每次收到确认时,都不断增加允许发送的未确认数据包数量,那么在某个时候,我们就会达到极限。这个系统的妙处在于,当我们开始尝试以比路由器之间最薄弱的链路(实际上是链路)更快的速度发送数据包时,在某个时候,我们会发现最薄弱的链路断裂了。它会丢弃我们试图发送的数据包,因为我们试图发送它们的速度太快了。因此,来自另一端的确认会停止,因为数据不再通过。
TCP 会采取以下措施:如果未能接收数据,则采取不同的策略。随着时间的推移,实际的拥塞避免策略已经发生了很大变化。有 Tahoe 和 Reno 等名称,如果您在 Google 和 Wikipedia 上搜索,还会看到许多其他名称,这些名称具体说明了具体的行为。但其理念是,当发送方意识到由于缺少确认而无法再发送数据时,它会迅速降低发送速率。通常,它会将其减半。因此,它会大幅降低发送速率,然后再重新增加发送速率。
因此,本质上,这意味着丢失数据包是“我们无法以更快的速度发送数据”的信号,而整个互联网上连接两端的 TCP 发送者总是试图以超过两个端点之间可用的最大速度(即最薄弱的链路,无论它在哪里)的速度发送,并且总是将其推到极限。因此,如果存在一个比其发送数据包能力更弱的点,它们就会找到它,因为它们会将数据包发送出去。只要有数据要发送,并且它们有高带宽连接,发送者就会增加发送速率,即未完成数据包的数量,即在确认返回时允许即时发送的数据包,它会积极地不断增加该数字,直到将其推得太远。然后它会大幅回退,然后再次向前移动。
因此,TCP 连接之间实际上正在发生什么,我不知道占比是多少,但互联网上绝大部分流量都是通过 TCP 连接进行的。我们所有操作系统的内核,即所谓的 TCP 堆栈,都有这些计数器。当我们发送文件、上传大文件或接收网页时,另一端的服务器也在做同样的事情。它会在单个连接的基础上推送尽可能多的尚未确认的数据包,增加数据包速率,直到达到开始失败或卡顿的点。然后它会后退,让事情恢复,然后再次开始工作。
因此,这最终成为一种自我调节的系统,考虑到限制因素,我的意思是,它看起来确实有点古怪和粗糙。”
答案3
因此,要限制下载速度,您有两种选择:
1)指示服务器以更慢的速度向您发送数据 - 我认为 TCP 或 HTTP 中没有任何协议功能可以请求这样做。
2)通过限制上传速度来更慢地确认数据包,同时也会破坏您的上传速度。
3) 您的路由器/防火墙设备将传入数据放入 QoS 存储桶,并仅以您请求的速率清空该存储桶。传入数据将适应该速度,因为内部的计算机只会以该速度看到确认接收。此外,偶尔(故意)丢弃数据包确实可以很好地减慢连接速度。
当尝试寻找处理此问题的设备时,请在配置/文档中查找 QoS(服务质量)。Linux(或 BSD)机器对此也很方便。
答案4
HTTP 协议不提供限制使用带宽的功能,即使有,那也是客户端设置,网络管理员无法控制。
带宽限制(也称为“服务质量”)通常在路由器/防火墙上进行管理,它们处理往返于网络的所有传入和传出的流量;支持此功能的路由器/防火墙通常允许您配置策略,例如“让任何单个客户端计算机最多使用所有可用带宽的 10%”,或“让 SMTP 优先于 FTP,以便即使有人正在进行大量下载,电子邮件仍可流通”。
如何实现这一点取决于所使用的路由器/防火墙,但最基本的方法是丢弃超出配置限制的数据包;TCP 将确保它们被重新传输,并最终能够通过瓶颈。