【发布时间】:2013-03-19 23:14:20
【问题描述】:
我说的是下载管理器中的速度限制。例如,在 Internet 下载管理器中有一个选项:
它如何限制速度?我的意思是,有某种 Windows API 吗?如果它是一个 Linux 应用程序呢?
【问题讨论】:
我说的是下载管理器中的速度限制。例如,在 Internet 下载管理器中有一个选项:
它如何限制速度?我的意思是,有某种 Windows API 吗?如果它是一个 Linux 应用程序呢?
【问题讨论】:
在 Windows 中可能有几种方法可以做到这一点:
应用程序本身可以通过监控自己的比特率并根据需要在套接字上的recv() 或read() 调用之间休眠来隐式限制下载速度。
我怀疑 Internet 下载管理器可能会将自身安装为本地 HTTP 代理并配置浏览器以通过它路由所有请求。然后使用我上面描述的简单技术,使用它自己的网络代码以适当的速率流式传输下载。查看是否为您的浏览器配置了 http 代理 - 如果它正在这样做,这应该是一个很好的提示。
另一种技术是使用 Winsock 分层服务提供程序或过滤器驱动程序。尝试从命令行输入netsh winsock show catalog(已经安装了很多系统)。
Winsock 本身有一个旧的QOS API 可以在特定套接字上进行“流量整形”。 (如果内存服务,它甚至有一些系统策略支持,可以在应用程序外部进行配置)。
【讨论】:
我在 Linux 上做的一个项目实际上需要这个。我注意到传输具有限制下载速度的能力。翻看他们的源代码,你会发现 curl 遍地都是。
话虽如此,libcurl 似乎是 C\C++ 程序的一个很好的 api。 api 看起来并没有那么糟糕,文档也没有。
参见 CURLOPT_MAX_SEND_SPEED_LARGE 和 CURLOPT_MAX_RECV_SPEED_LARGE:
man curl_easy_setopt(3)
【讨论】:
@selbie 为您指明了正确的方向。我只是想详细说明:
收件人实际上只能控制大型下载的速度。对于非常小的下载,TCP 慢启动将控制带宽。不那么小的下载(直到协商的 TCP 窗口大小限制)将在连接允许的情况下以最快的速度完成,因为 TCP 流控制取决于 ACK,并且发送方不会等待任何 ACK。对于中等大小的下载(直到套接字缓冲区大小),操作系统将立即确认数据包,这些将在连接允许的情况下尽快完成,并且应用程序无法控制。只有一旦套接字缓冲区填满,应用程序才会延迟recv 并导致限制传输速率的背压。需要网络堆栈内部的解决方案(QOS 或过滤器驱动程序)来缩短传输时间。
如果协议提供了一种要求发送方设置传输速度的方法,那将是最有效的。
【讨论】:
在 Linux 上,我不知道它实际上是如何完成的,但您可以随时查看执行此操作的应用程序的源代码(例如 wget 和 --limit-rate)或只是 strace 他们以了解相关系统来电。
如果我必须在网络应用程序中编写带宽限制,我只需在每次缓冲区传输后执行此操作:我将计算当前带宽,并等待(不传输)适当的延迟以避免溢出限制。
在 Linux 上,poll 和 select 系统调用可以等待一些延迟,直到输入或输出可用。而只是等待,使用usleep 或nanosleep 系统调用等。
【讨论】: