QtのHTTP要求マルチスレッドブロックダウンロード――上(ダウンロードファイルサイズ取得)


簡単に述べる
QtのHTTPリクエストダウンロード(ブレークポイントの継続をサポート)記事では、Qtの方法でHTTPリクエストダウンロードファイルを行い、同時にブレークポイントの継続を行うことができます.この記事はこの記事の続編です.
私达は一般的にネット上でソフトウェア、映画、ファイルなどをダウンロードして、大部分は雷を使ってダウンロードして、雷のダウンロードが相対的に速いためです.私たちの日常生活の中で、雷を使って大きなファイルをダウンロードする時、とてもネットのスピードを占めて、甚だしきに至っては家庭のLAN全体の帯域幅を占有します.时にはブラウザがホームページを開けないことがありますが、迅雷には速度制限機能があり、正常なインターネットを保護することができます.次に図を見ます.
Qt 之 HTTP 请求 多线程分块下载——上(获取下载文件大小)_第1张图片
これは最新の迅雷9のインタフェースで、私达は絵輪の地方を见て、ここに1つの原始のアドレスのスレッドの数があって、デフォルトは5で、范囲は1-10で、つまり迅雷は1つのダウンロードの任务を5つのスレッドに分けてそれぞれダウンロードして、5つのスレッドは1つのスレッドに対して、资源の占有の比较的に多くて、ダウンロードのスピードは比较的に速いです.
スレッドが多ければ多いほどダウンロード速度が速くなるということですか?
必ずしもそうではありません.ダウンロード速度はネットワークの最大帯域幅を見るため、最大ダウンロード速度はブロードバンド事業者が提供する最大帯域幅(ローカルコンピュータのネットワークカード)を超えることはできませんが、複数のスレッドは1つのスレッドに対して全体的な速度が上昇するに違いありません.次の図のように、矩形ごとにパイプと見なすことができます.水は上の赤いパイプから流れています.緑のパイプは地元のパソコンのネットカードです.一般的にはネットカードは百兆ネットカードです.ネットの帯域幅に対して、この緑のパイプは比較的太いので、パソコンのネットカードは一般的にネットの速度を制限しません.下の茶色のパイプを見ると、ブラウザなど他のソフトウェアが占有するネット速度を示していますが、青いパイプは雷のダウンロードが占有するネット速度で、左右の2つの図を比較すると、3本のパイプの水流量>=1本のパイプの水流量、つまりスレッドが多いほど占有する資源が比較的多いことがわかります.
Qt 之 HTTP 请求 多线程分块下载——上(获取下载文件大小)_第2张图片
スレッドは多ければ多いほどいいですか?
必ずしもそうではない.赤いパイプの半径は固定されているからだ.すなわち、水流量は一定であり、下の青いパイプを増やし続けると、パイプ1本あたりの水流量が相対的に減少する.作成されたパイプが多ければ多いほど、必然的により多くのリソースが消費されるので、スレッドが多ければ多いほど良いわけではありません.スレッドを一定の範囲内に制御するには,迅雷では1つのタスクのスレッドを1~10の範囲内に制御する.
Qtの方法でHTTPをダウンロードする場合は、まずファイルをブロック化し、各ブロックに1つのスレッドを作成してダウンロードすることができます.マルチスレッドブロックダウンロードのメリットも説明していますが、スレッドの数は自分でコントロールする必要があります.次に、HTTPで1つのファイルの総サイズを要求する方法について説明します.
コードの道
qint64 getFileTotalSize(QString url, int tryTimes)
{
    qint64 size = -1;

    if (tryTimes <= 0)
    {
        tryTimes = 1;
    }

    do 
    {
        QNetworkAccessManager manager;
        //     ,           ;
        QEventLoop loop;
        //   ,      ;
        QTimer timer;

        //    ,           ;
        QNetworkReply *reply = manager.head(QNetworkRequest(url));
        if (!reply)
            continue;

        connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
        connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));

        timer.start(2000);
        loop.exec();

        if (reply->error() != QNetworkReply::NoError)
        {
            qDebug() << reply->errorString();
            continue;
        }
        if (reply->error() != QNetworkReply::NoError)
        {
            //       ;
            qDebug() << reply->errorString();
            continue;
        }
        else if (!timer.isActive())
        {
            //       ,        ;
            qDebug() << "Request Timeout";
            continue;
        }
        timer.stop();

        QVariant var = reply->header(QNetworkRequest::ContentLengthHeader);
        size = var.toLongLong();
        reply->deleteLater();
        break;
    } while (tryTimes--);

    return size;
}

たんじゅんぶんせき
上記では、HTTPリクエストでダウンロードファイルのサイズを取得する方法を提供しています.私たちは1つのファイルをブロックダウンロードするため、まずファイルのサイズを知る必要があります.そうしないと、どのようにブロックしますか.
qint64 getFileTotalSize(QString url, int tryTimes)
1つ目のパラメータはファイルをダウンロードするurlで、2つ目のパラメータはリクエストの回数で、何らかの原因でリクエストが失敗する可能性がある(例えば、現在のネットワークがあまりよくない、あるいはファイルサーバが忙しい)ため、3回の試みをして、できるだけリクエストが成功することを保証しました.
要求回数についてはまず判断を行い,回数が負またはゼロであることを防止する.do-whileループでリクエストファイルサイズを行います.
ここでは,Qtにおけるイベントループを用いてファイルサイズのリクエストの終了を待ち,ファイルリクエストの終了後にイベントループを終了する.リクエストが遅すぎたり、イベントサイクル時間が長すぎたりするのを防ぐため、ここでタイムアウトを加え、2 sを超えてイベントサイクルを終了し、再リクエストします.(ファイルヘッダ情報を要求するのは、ネットワークが悪いかファイルサーバに問題が発生しない限り、一般的には時間がかかるためです.具体的なタイムアウト時間は状況によって異なります)
我々はreply->header(QNetworkRequest::ContentLengthHeader)を使用する.に表示されます.パラメータは具体的に下図を見ることができます.
Qt 之 HTTP 请求 多线程分块下载——上(获取下载文件大小)_第3张图片
テール
上記の説明では、ダウンロードするファイルのサイズを取得し、コードも簡単ですが、これは最初のステップです.次の記事では、ブロックを分割し、複数のスレッドを作成してそれぞれのファイルブロックをダウンロードするとともに、ダウンロード情報を保存し、プログラムが2回目に開いたときにダウンロードを継続する方法について説明します.