Qt QNetworkReply readAll возвращает пустой при повторном запросе того же URL

Это чисто для целей тестирования и для моего любопытства. Я использую свой класс DataDownloader для получения списка данных с сервера. Он работает с разными URL, как Http: // крошечные-файлы URL, Http: // большой файл-URL. Но если я передам в двух одинаковых URL, Http: // крошечные-файлы URL, Http: // крошечные-файлы URL, и данные из Http: // крошечные-файлы URL достаточно маленький, тогда второй ответ от QNetworkAccessManager пуст. Однако два Http: // большой файл-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);
}
}

2

Решение

Я думаю здесь isComplete испускается до того, как вы подключите его к downloadPluginsслот. Попробуйте сначала подключить этот сигнал, а затем выполните действие загрузки:

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 Сигнал один раз там. Затем вы можете предоставить URL в качестве аргумента в download слот.

1

Другие решения


По вопросам рекламы [email protected]