如何限制下载速度?
最近我问了这个问题。但答案不符合我的要求,而且我知道文件托管提供商确实设法限制速度。所以我想知道执行此操作的通用算法/方法是什么(我的意思是下载技术) - 特别是限制单个连接/用户下载速度。
@back2dos 我想为特定用户提供特定的下载速度(当然与硬件功能相对应),或者换句话说,让用户能够以 20kb/s 的速度下载某些特定文件。当然,我希望有能力将其更改为其他值。
Lately I've asked this question. But the answer doesn't suit my demands, and I know that file hosting providers do manage to limit the speed. So I'm wondering what's the general algorithm/method to do that (I do mean downloading technique) - in particular limiting single connection/user download speed.
@back2dos I want to give a particular user a particular download speed (corresponding to hardware capabilities of course) or in other words give user ability to download some particular file with lets say 20kb/s. Surely I want to have an ability to change that to some other value.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用令牌桶(http://en.wikipedia.org/wiki/Token_bucket)
You could use a token bucket ( http://en.wikipedia.org/wiki/Token_bucket)
如果不提及平台/语言,就很难回答,但“漏桶”算法可能是最合适的:
http://en.wikipedia.org/wiki/Leaky_bucket
Without mention of platform/language, it's difficult to answer, but a "leaky bucket" algorithm would probably be the best fit:
http://en.wikipedia.org/wiki/Leaky_bucket
好吧,因为这个答案非常笼统,所以这里有一个非常简单的普通 TCP 方法:
将所有下载连接的资源处理程序放入一个列表中,与有关请求的数据的信息配对,然后循环遍历它。然后将所需数据的一大块写入套接字,大约1.5K,据我所知,这是最常用的最大段大小。当您位于列表的最后位置时,您可以重新开始。在重新开始之前,只需等待获得所需的平均带宽即可。
请注意,如果太多客户端的带宽低于您允许的带宽,那么您的 TCP 缓冲区可能会爆炸。某些 TCP 绑定允许查找一个套接字当前缓冲的数据的大小。如果超过阈值,您可以简单地跳过该套接字。
另外,如果连接的客户端太多,实际上您将没有足够的时间写入所有套接字,因此在一个循环之后,您“必须等待负时间”。在这种情况下,增加块大小可能会加快速度,但在某些时候您的服务器将停止变得更快。
更简单的方法是在客户端执行此操作,但这可能会产生大量开销。最简单的想法是让客户端每 50 毫秒请求 1K 数据(假设您需要 20KB/s)。您甚至可以通过 HTTP 执行此操作,但我强烈建议使用更大的块大小,因为 HTTP 的开销很大。
我的猜测是,最好的方法是尝试找到一个能够开箱即用地执行此类操作的网络服务器。我认为 Apache 有许多用于各种配额的模块。
问候
后退2dos
Well, since this answer is really general, here's a very simple approach for plain TCP:
You put the resource handlers of all download connection into a list, paired up with information about what data is requested, and loop through it. Then you write a chunk of the required data onto the socket, maybe about 1.5K, which is the most commonly used maximum segment size, as far as I know. When you're at the and of the list, you start over. Before starting over, simply wait to get the desired average bandwidth.
Please note, if too many clients have lower bandwidth than you allow, then your TCP buffer is likely explode. some TCP bindings permit finding the size of currently buffered data for one socket. if it exceeds a threshold, you can simply skip the socket.
Also, if too many clients are connected, you will actually not have enough time to write to all the sockets, thus after one loop, you "have to wait for a negative time". Increasing the chunk size might speed up things in such scenarios, but at some point your server will stop getting faster.
A more simple approach is to do this on the client side, but this may generate a lot of overhead. The dead simple idea is to have the client request 1K every 50ms (assuming you want 20KB/s). You can even do that over HTTP, although I strongly suggest bigger chunk size, since HTTP has enourmous overheads.
My guess is, the best is to try to find a webserver capable of doing such things out of the box. I think Apache has a number of modules for al kinds of quota.
greetz
back2dos