adnan kamili
adnan kamili

Reputation: 9485

Is it possible to control download speed using QNetworkAccessManager

Can we restrict QNetworkAccessManager from consuming whole bandwidth, by restricting the download speed, as we do see such options available with almost every download manager?

Upvotes: 3

Views: 2078

Answers (1)

leemes
leemes

Reputation: 45745

This is not possible out of the box. But have a look at the Qt Torrent Example, especially the class RateController (ratecontroller.h | ratecontroller.cpp). This class does almost what you want by controlling not only one but a set of connections.

However, this rate controller is operating on QTcpSockets (to be exact on PeerWireClients), so you need to change the type of the "peers" to be QIODevice, which I hope isn't that hard, since PeerWireClient inherits from QTcpSocket, which itself inherits from QIODevice:

 // old
 void addSocket(PeerWireClient *socket);
 // new
 void addDevice(QIODevice *device);

(Note that the RateController from the Torrent example controlls both upload and download, but you only need to control the download rate. So you can remove unnecessary code.)

Then you need to make requests made by your QNetworkAccessManager use this rate controller. This can be done by reimplementing QNetworkAccessManager and overwriting (extending) the method QNetworkAccessManager::createRequest, which will be called whenever a new request gets created. This method returns the QNetworkReply* (which inherits from QIODevice*) where the download will be read from, so telling the rate controller to control this device will limit the download rate:

QNetworkReply *MyNetworkAccessManager::createRequest(
                QNetworkAccessManager::Operation op,
                const QNetworkRequest &req,
                QIODevice *outgoingData)
{
    // original call to QNetworkAccessManager in order to get the reply
    QNetworkReply *reply = QNetworkAccessManager::createRequest(op, req, outgoingData);

    // add this reply (which is a QIODevice*) to the rate controller
    rateController.addDevice(reply);

    return reply;
}

You will not have to subclass QNetworkAccessManager if you already know the pieces of code where you actually perform requests. The methods get() and post() return a QNetworkReply* which you can also just add to the rate controller. (But this way, you manually do this outside of the manager, which is doesn't fulfill the concept of information/implementation hiding, in this case the fact that downloads are rate-controlled.)

Upvotes: 2

Related Questions