Qt QNetworkReply readAll 在再次请求相同的 url 时返回空

Posted

技术标签:

【中文标题】Qt QNetworkReply readAll 在再次请求相同的 url 时返回空【英文标题】:Qt QNetworkReply readAll returns empty when request the same url again 【发布时间】:2015-02-06 18:16:24 【问题描述】:

这是出于纯粹的测试目的和我的好奇心。我使用我的 DataDownloader 类从服务器获取数据列表。它适用于不同的网址,例如http://tiny-file-url、http://big-file-url。但是如果我传入两个相同的url,http://tiny-file-url,http://tiny-file-url,而http://tiny-file-url的数据很小,那么QNetworkAccessManager的第二个回复是空的。然而两个http://big-file-url 似乎工作。我想知道 QNetworkAccessManager 在从同一个 url 请求小数据时是否有一些魔力?我似乎无法在 Qt 文档站点上获得任何相关信息。

这是我的DataDownloader 课程:

class DataDownloader : public QObject

    Q_OBJECT

public:
    explicit DataDownloader(QObject* parent = 0);
    virtual ~DataDownloader();

    QByteArray data() const;
    void cancel();
    void download(QUrl url);

    signals:
    void isComplete();

    private slots:
    void complete(QNetworkReply* reply);

    private:
    QNetworkAccessManager m_NetworkManager;
    QByteArray m_Data;
    QNetworkReply* m_pReply;
;

DataDownloader::DataDownloader(QUrl url, QObject* parent) :QObject(parent)

    connect(&m_NetworkManager, SIGNAL(finished(QNetworkReply*)),
            SLOT(complete(QNetworkReply*)));


DataDownloader::~DataDownloader()



void DataDownloader::complete(QNetworkReply* reply)

    // in the first download it returns data
    // but the second time m_Data is empty
    m_Data = reply->readAll();
    reply->deleteLater();

    if (!m_Data.isEmpty()) 
        // no signal on the second try
        emit isComplete();
    


QByteArray DataDownloader::data() const

    return m_Data;


void DataDownloader::cancel()

    m_pReply->abort();


void DataDownloader::download(QUrl url)

    QNetworkRequest request(url);
    m_pReply = m_NetworkManager.get(request);

调用这个DataDownloader的代码如下:

void PluginManager::downloadPlugins()

    m_DownloadIndex++;

    savePlugin();

    if (m_DownloadIndex < m_PluginList.size()) 
        QUrl url;
        // alway return the same url here
        QString pluginUrl = getPluginUrl(m_PluginList.at(m_DownloadIndex));
        url.setUrl(pluginUrl);

        if (m_pPluginDownloader == NULL) 
            m_pPluginDownloader = new DataDownloader();
            // call this function again when isComplete is signaled
            connect(m_pPluginDownloader, SIGNAL(isComplete()), this, SLOT(downloadPlugins()));
        
        m_pPluginDownloader->download(url);
    

【问题讨论】:

每日随机代码建议:最好只创建一个 QNetworkAccessManager 而不是每个下载者一个。 顺便说一句,您是否 100% 有信心 tiny-file-url 始终按预期工作? 我对此很有信心,因为我可以将数据下载为文件(包含调试文本)并使用编辑器打开。 抱歉,如果您的意思是实际的 tiny-file-url 是否正常工作,这只是为了说明,它不是有效的 url。 不,你明白了,我的意思是你的实际网址:) 【参考方案1】:

我认为isComplete 在您将其连接到downloadPluginsslot 之前已发出。尝试先连接此信号,然后执行下载操作:

m_pPluginDownloader = new DataDownloader(url);

connect(m_pPluginDownloader, SIGNAL(isComplete()), this, SLOT(downloadPlugins()));

m_pPluginDownloader.download();

不要在构造函数中执行 get 操作,而是在名为 download 的插槽中执行它:

void DataDownloader::download()

    QNetworkRequest request(url);
    m_pReply = m_NetworkManager.get(request);

另外一点是不必每次都创建一个DataDownloader 的新实例。您可以在PluginManager 的构造函数中创建一个实例,并在那里连接isComplete 信号。然后,您可以在 download 插槽中提供 url 作为参数。

【讨论】:

嗨内贾特,感谢您的回复。我已经尝试过你的建议,它的工作原理和以前一样。我在第二次下载时仍然得到空数据。 嗨 Nejat,这个问题似乎只发生在两个相同的 url 上,并且来自这些 url 的数据很小。我将使用两个包含小数据的不同 url 进行测试,看看它是否有任何区别。 所以有我的测试结果:tiny-file-url, big-file-url 工作 big-file-url, big-file-url 工作 tiny-file-1-url, tiny-file -2-url 工作 tiny-file-url,tiny-file-url 在第二次请求时返回空

以上是关于Qt QNetworkReply readAll 在再次请求相同的 url 时返回空的主要内容,如果未能解决你的问题,请参考以下文章

使用 QNetworkAccessManager 从 Web 检索数据:文件已下载但 QNetworkReply::readAll 返回 null

从 QNetworkReply 读取未解码的数据

readAll在qt中是啥意思

QnetworkReply 错误 - Symbian Qt

Qt Jambi:访问 QNetworkReply 的内容

Qt 使用 QNetworkReply 获取外部 IP 地址