📄 ratecontroller.cpp
字号:
/******************************************************************************** Copyright (C) 2004-2006 Trolltech ASA. All rights reserved.**** This file is part of the example classes of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "peerwireclient.h"#include "ratecontroller.h"#include <QtCore>Q_GLOBAL_STATIC(RateController, rateController)RateController *RateController::instance(){ return rateController();}void RateController::addSocket(PeerWireClient *socket){ connect(socket, SIGNAL(readyToTransfer()), this, SLOT(scheduleTransfer())); socket->setReadBufferSize(downLimit * 4); sockets << socket; scheduleTransfer();}void RateController::removeSocket(PeerWireClient *socket){ disconnect(socket, SIGNAL(readyToTransfer()), this, SLOT(scheduleTransfer())); socket->setReadBufferSize(0); sockets.remove(socket);}void RateController::setDownloadLimit(int bytesPerSecond){ downLimit = bytesPerSecond; foreach (PeerWireClient *socket, sockets) socket->setReadBufferSize(downLimit * 4);}void RateController::scheduleTransfer(){ if (transferScheduled) return; transferScheduled = true; QTimer::singleShot(50, this, SLOT(transfer()));}void RateController::transfer(){ transferScheduled = false; if (sockets.isEmpty()) return; int msecs = 1000; if (!stopWatch.isNull()) msecs = qMin(msecs, stopWatch.elapsed()); qint64 bytesToWrite = (upLimit * msecs) / 1000; qint64 bytesToRead = (downLimit * msecs) / 1000; if (bytesToWrite == 0 && bytesToRead == 0) { scheduleTransfer(); return; } QSet<PeerWireClient *> pendingSockets; foreach (PeerWireClient *client, sockets) { if (client->canTransferMore()) pendingSockets << client; } if (pendingSockets.isEmpty()) return; stopWatch.start(); bool canTransferMore; do { canTransferMore = false; qint64 writeChunk = qMax<qint64>(1, bytesToWrite / pendingSockets.size()); qint64 readChunk = qMax<qint64>(1, bytesToRead / pendingSockets.size()); QSetIterator<PeerWireClient *> it(pendingSockets); while (it.hasNext() && (bytesToWrite > 0 || bytesToRead > 0)) { PeerWireClient *socket = it.next(); if (socket->state() != QAbstractSocket::ConnectedState) { pendingSockets.remove(socket); continue; } bool dataTransferred = false; qint64 available = qMin<qint64>(socket->socketBytesAvailable(), readChunk); if (available > 0) { qint64 readBytes = socket->readFromSocket(qMin<qint64>(available, bytesToRead)); if (readBytes > 0) { bytesToRead -= readBytes; dataTransferred = true; } } if (upLimit * 2 > socket->bytesToWrite()) { qint64 chunkSize = qMin<qint64>(writeChunk, bytesToWrite); qint64 toWrite = qMin(upLimit * 2 - socket->bytesToWrite(), chunkSize); if (toWrite > 0) { qint64 writtenBytes = socket->writeToSocket(toWrite); if (writtenBytes > 0) { bytesToWrite -= writtenBytes; dataTransferred = true; } } } if (dataTransferred && socket->canTransferMore()) canTransferMore = true; else pendingSockets.remove(socket); } } while (canTransferMore && (bytesToWrite > 0 || bytesToRead > 0) && !pendingSockets.isEmpty()); if (canTransferMore) scheduleTransfer();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -