2015-02-06 3 views
2

이것은 순수한 테스트 목적 및 호기심 때문입니다. 내 DataDownloader 클래스를 사용하여 서버에서 데이터 목록을 가져옵니다. http://tiny-file-url, http://big-file-url과 같은 다른 URL에서 작동합니다. 그러나 두 개의 동일한 URL (http://tiny-file-url, http://tiny-file-url)을 전달하고 http://tiny-file-url의 데이터가 매우 작 으면 QNetworkAccessManager의 두 번째 응답이 비어 있습니다. 그러나 두 http://big-file-url가 작동하는 것 같습니다. 같은 URL에서 작은 데이터를 요청할 때 QNetworkAccessManager가 마술을하는지 궁금합니다. Qt 문서 사이트에서 관련 정보를 얻지 못하는 것 같습니다.QT QNetworkReply readAll은 같은 URL을 다시 요청할 때 비어있는 것을 반환합니다.

여기 내 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

오늘의 임의 코드 제안 : 다운로더 당 하나가 아닌 단지 하나의'QNetworkAccessManager'를 만드는 것이 훨씬 더 좋은 생각입니다. – peppe

+0

BTW, http : // tiny-file-url은 항상 예상대로 작동합니까? – alediaferia

+0

데이터를 파일 (디버그 텍스트 포함)로 다운로드하고 편집기로 열 수 있기 때문에 나는 이에 대해 확신합니다. – Jerry

답변

1

난 당신이 downloadPlugins 슬롯에 연결하기 전에 isComplete이 방출 여기에 생각합니다. 먼저 신호를 연결하려고하고 다운로드 작업을 수행

대신 생성자에서 가져 오기 작업을 수행하는, download라는 슬롯에 그것을 할
m_pPluginDownloader = new DataDownloader(url); 

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

m_pPluginDownloader.download(); 

:

void DataDownloader::download() 
{ 
    QNetworkRequest request(url); 
    m_pReply = m_NetworkManager.get(request); 
} 

또 다른 포인트는 그렇지 않은 것입니다 매번 DataDownloader의 새 인스턴스를 만드는 데 필요합니다. PluginManager의 생성자에서 인스턴스를 만들고 isComplete 신호를 한 번 연결할 수 있습니다. 그런 다음 download 슬롯에 url을 인수로 제공 할 수 있습니다.

+0

안녕하세요 Nejat, 답장을 보내 주셔서 감사합니다. 나는 당신의 제안을 시도했다, 이전과 동일하게 작동한다. 두 번째 다운로드시 여전히 빈 데이터가 표시됩니다. – Jerry

+0

안녕하세요 Nejat,이 문제는 두 개의 동일한 URL에서만 발생하며 해당 URL의 데이터는 작습니다. 차이가 있는지 확인하기 위해 작은 데이터가 들어있는 두 개의 서로 다른 URL로 테스트 할 것입니다. – Jerry

+0

내 테스트 결과가 있습니다. 큰 파일 URL, 큰 파일 URL 작동 큰 파일 URL, 큰 파일 URL 작동 작은 파일 1 URL, 작은 파일 2 URL 작동 두 번째 요청시 tiny-file-url, 작은 파일 -URL 반환 빈 – Jerry