I\'m talking about speed limiting in download managers. For example, in Internet Download Manager there is a an option :
I actually need this for a project I'm doing on Linux. I noticed that transmission had the ability to limit download speeds. Peeking through their source code, you can find curl all over it.
With that said, libcurl seems to be a good api for C\C++ programs. The api doesn't look that bad and neither does the documentation.
see CURLOPT_MAX_SEND_SPEED_LARGE and CURLOPT_MAX_RECV_SPEED_LARGE in:
man curl_easy_setopt(3)
and the libcurl homepage
@selbie's pointing you in the right direction. I just want to elaborate:
The recipient can really only control speed for large downloads. For really small downloads, TCP slow-start will control bandwidth. Not-quite-as-small downloads (up to the negotiated TCP window size limit) will complete as fast as the connection allows, because TCP flow control depends on ACKs, and the sender won't be waiting for any ACKs. For medium size downloads (up to the socket buffer size) the OS will acknowledge the packet immediately, these will complete as fast as the connection allows and the application has no control. Only once the socket buffer fills, can the application delay recv
and cause backpressure that limits the transmission rate. Solutions inside the network stack (QOS or filter driver) are needed for shorter transmissions.
If the protocol provides a way to ask the sender to set the transmit speed, that would be most effective.
There are potentially several ways this can be done in Windows:
An application itself can implicitly limit the download speed by monitoring it's own bitrate and sleeping between recv()
or read()
calls on the socket as needed.
I suspect Internet Download Manager may be installing itself as a local HTTP proxy and configuring the browsers to route all requests through it. And then uses its own networking code to stream the download at an appropriate rate using the simple technique I described above. Look to see if there is an http proxy configured for your browser - that should be a good hint if this is what it is doing.
Another technique is to use a Winsock Layered Service Provider or filter driver. Try typing netsh winsock show catalog
from the command line (there are a lot of system ones already installed).
And Winsock itself has an old QOS API that can do "traffic shaping" on a particular socket. (And if memory serves, it even has some system policy support where it can be configured externally outside of the app).
On Linux, I have no idea how it is done actually, but you could always look at the source code of applications doing this (eg wget
with --limit-rate
) or just strace
them to understand the involved system calls.
If I had to code a bandwidth limitation in a network application, I would simply do that after each buffer transmission: I would compute the current bandwidth, and would wait (without transmitting) the suitable delay to avoid overflowing the limitation.
On Linux, poll
and select
system calls can wait some delay till input or output is available. And to just wait, use usleep
or nanosleep
system calls, etc.