将大小限制添加到 QNetworkReply

Add size limit to QNetworkReply

本文关键字:添加 QNetworkReply      更新时间:2023-10-16

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

我正在使用QNetworkReply class。

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

第二次检查,我查看了信号下载进度(qint64 bytesReceived, qint64 bytesTotal)。不过,我可以检查一下,如果字节接收太大,我可以中止。但我不确定有两个动机:首先,正如文档中所写

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

其次,我不知道我什么时候会收到这个信号。也许为时已晚...

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

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

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

第二

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

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

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

我找到的最好的解决方案是使用 readyRead 信号(QNetworkReply 源自 QIODevice),然后在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内部,这是一个连接到readyRead和文档的slot

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

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

PS:我仍然对更好的解决方案持开放态度,可能是Qt中的原生解决方案。