0

在我的应用程序中,使用 Qt5 完成,当我从互联网下载数据时,我想设置一个安全系统。首先,我想检查我正在下载多少字节,如果是这种情况,我会中止。我想设置下载字节的最大限制,如果超过则中止。

我正在使用QNetworkReply类。

首先我检查了size()函数,但是那时我已经收到了所有数据(请求完成),所以这还不够。

第二次检查,我查看了信号downloadProgress(qint64 bytesReceived, qint64 bytesTotal)。不过,如果 bytesReceived 太大,我可以检查并中止。但我不确定有两个动机:首先,如文档中所写

请注意,bytesReceived 和 bytesTotal 的值可能与 size()、通过 read() 或 readAll() 获得的总字节数或 header(ContentLengthHeader) 的值不同。原因是可能存在协议开销,或者在下载过程中可能会压缩数据。

第二,不知道什么时候能收到这个信号……也许来不及了……

最后,我检查了setReadBufferSize(qint64 size)。这似乎是一个很好的解决方案,但我不确定文档中的以下两行:首先,

一旦此缓冲区已满,QNetworkReply 将尝试停止从网络读取(即 bytesAvailable() 返回大小或更多)

试试是什么意思?我应该依靠它吗?

第二,

与 QAbstractSocket::setReadBufferSize() 不同,QNetworkReply 不能保证读取缓冲区大小的精度。也就是说,bytesAvailable() 可以返回超过大小。

所以,看来我不能依靠一个精确的限制来设定。

有人可以建议我实现它的最佳方法吗?

4

1 回答 1

0

我找到的最佳解决方案是使用readyRead信号(QNetworkReply派生自QIODevice),然后自己在 a 中实施安全检查slot

void onReadyRead()
{
    for (;;)
    {
        QByteArray currentDataRead = httpReply->read(100); // Just read some bytes
        if ( currentDataRead.isEmpty() )
            return;

        myResponseBody.append(currentDataRead);
        if (myResponseBody.size() > myMaxResponseSize) // check my limit
        {
            qDebug() << "Error: response size bigger than expected - aborting";
            httpReply->abort();
        }
    }
}

注意:需要 inifitefor(;;)循环和检查if ( currentDataRead.isEmpty() ) return;,以便在最后不遗漏一些字节,因为我们在里面onReadyRead是与文档的slot连接:readyRead

readyRead() 不会递归发出;如果您重新进入事件循环或在连接到 readyRead() 信号的插槽内调用 waitForReadyRead(),则不会重新发送该信号(尽管 waitForReadyRead() 仍可能返回 true)。

--------------------

PS:我仍然愿意接受更好的解决方案,可能是 Qt 原生的

于 2018-07-16T09:41:05.117 回答