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

时间:2015-02-06 18:16:25

标签: c++ qt url qnetworkreply

这是出于纯粹的测试目的和我的好奇心。我使用DataDownloader类从服务器获取数据列表。它适用于不同的网址,例如http://tiny-file-urlhttp://big-file-url。但是,如果我传入两个相同的网址http://tiny-file-urlhttp://tiny-file-url,并且来自http://tiny-file-url的数据非常小,那么QNetworkAccessManager的第二个回复为空。然而,两个http://big-file-url似乎有效。我想知道QNetworkAccessManager在从同一个网址请求小数据时是否有所作为?我似乎无法在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);
    }
}

1 个答案:

答案 0 :(得分:1)

我认为在将isComplete连接到downloadPlugins广告位之前会发出m_pPluginDownloader = new DataDownloader(url); connect(m_pPluginDownloader, SIGNAL(isComplete()), this, SLOT(downloadPlugins())); m_pPluginDownloader.download(); 。尝试先连接此信号,然后执行下载操作:

download

不是在构造函数中执行get动作,而是在名为void DataDownloader::download() { QNetworkRequest request(url); m_pReply = m_NetworkManager.get(request); } 的插槽中执行:

DataDownloader

另一点是,没有必要每次都制作PluginManager的新实例。您可以在isComplete的构造函数中创建一个实例,并在那里连接download信号。然后,您可以在{{1}}广告位中提供网址作为参数。