2014-05-16 7 views
1

현재 QFtp와 관련된 이상한 문제에 직면하고 있습니다. FTP 서버에서 여러 파일을 다운로드하려고하지만 y 방향으로 x 파일을 다운로드 한 후 ftp->get() 명령이 완료되면 파일이 채워지지만 SIGNALcommandFinished()의 방출이 없으므로 다른 파일을 다운로드하지 않습니다. 내가 너무 많은 요청을했기 때문에 그것이 생각 나는 있지만, 심지어 Sleep(2000)이 블록으로, 그 때문에 거부되었음을 처음에는QFtp commandFinished()를 방출하지 마십시오

void Ftp::commandFinished(int i, bool error) 
{ 

    if(ftp->currentCommand() == QFtp::Get) 
    { 
     if(error) 
     { 
      //blablabla-ERROR-blablabla 
     } 
     currentFile->close(); 
     filesToDownload.pop_front(); 
     processFileList(); 
    } 

    /**Gestion de la commande Login (authentification de l'utilisateur) 
    */ 
    if(ftp->currentCommand() == QFtp::Login) 
    {//not utile here} 

    /**Gestion de la commande ConnectToHost (connexion au serveur) 
    */ 
    if (ftp->currentCommand() == QFtp::ConnectToHost) 
    {//not utile here} 

    /**Gestion de la commande List (téléchargement d'un fichier) 
    */ 
    if(ftp->currentCommand() == QFtp::List) 
    { 
     if(error) 
     { 
      //Nananana-FAIL-nanana 
     } 

     //!Tri des fichiers à télécharger en fonction de leur dernière date de modification 
     if (!filesToDownload.isEmpty()) 
     { 
      currentPeripheral->setLastDownloadDate(newLastModifiedDate) ; 
      std::sort(filesToDownload.begin(),filesToDownload.end(),compareQUrlInfos); 
      processFileList(); 
     } 



    } 
} 

void Ftp::processFileList() 
{ 

QUrlInfo info; 

if (filesToDownload.isEmpty()) 
{ 
    //!Suicide de l'instance de Ftp 
    ftp->close(); 
    disconnect(this,0,0,0); 
    this->deleteLater(); 
    return ; 
} 

info = filesToDownload.first(); 
QDir dlDir(QString::number(currentPeripheral->getId())); 

//!Si un fichier a été téléchargé, on déclenche son traitement 
if (currentFile != nullptr) 
{ 
    emit(oneDownloadFinished(currentFile->fileName(),currentPeripheral)); 
    delete currentFile; 
    currentFile = nullptr; 
} 

//!On crée un répertoire de téléchargement si nécessaire 
if (!dlDir.exists()) 
{ 
    dlDir.mkdir("."); 
} 

//!on crée le fichier qui contiendra le téléchargement 
currentFile = new QFile(dlDir.filePath(info.name())); 

if(!currentFile->open(QIODevice::WriteOnly)) 
{ 
    delete currentFile; 
    currentFile = nullptr; 
    emit(writeToMonitoringConsole(QString("Erreur lors de la creation du fichier "+info.name()),"Error")); 
    return; 
} 


//Here I start (sometimes) a never ending fail 
ftp->get(info.name(), currentFile); 
} 

:

여기 내 코드입니다. 차단이 훨씬 더 빠르게 나타납니다. 나는 대개 약 30 개의 파일을 다운로드 할 수 있습니다 (행운의 70, 한 번 200을 관리 할 때!). Sleep(2000)으로 간신히 2-3 파일을 다운로드했습니다.

내게 실수입니까? QFTP에 제한 사항이 있습니까? 또는 다른 것 ? 편집

: 내가 그것을 게시 이후 SOMES 일을 테스트하고 dataTransferProgress() 신호를 모니터링 할 때 눈에 띄는 있었는지, 문제가있는 파일이 완전히 다운로드되어 있다는 점이다 (qDebug는 "88,928분의 88,928"라고)하지만 난 결코 commandFinished()를 입력하십시오.

내 슬롯 commandFinished은() 내 QFtp :: commandFinished 신호에 이런 식으로 연결되어

: 나는 결코에 대한 commandFinished를 수신하지 사용하십시오 FTPWidget 클래스와,

connect(ftp, SIGNAL(commandFinished(int,bool)), this, SLOT(commandFinished(int,bool))); 
+0

난 당신의 코드에서 어떤 commandFinished 신호가 표시되지 않는 등의 ID 으로 확인할 수 있습니까? 더 많은 코드를 공유해주십시오. – lpapp

+0

명령 중 하나가 완료되면 commandFinished()가 QFtp에 의해 생성됩니다. 정상적으로이 신호를 보내면 안됩니다. [Qt commmandFinished] (http://qt-project.org/doc/qt-4.8/qftp.html#commandFinished) – Karalix

+0

이것은 https://bugreports.qt.io/browse/QTBUG-19409 – x29a

답변

3

내가 거의 같은 일을보고 있어요을 GET 요청. dataTransferProgress() 신호는 다운로드 된 100 %와 그 모든 것을 안정적으로보고합니다.

나는 다음과 같이 설정 타임 아웃을 사용하여 주위를 해킹했습니다 타이머가 픽스 업 루틴에 연결되어

// Set up a single shot QTimer and connect it to a function to fix things 

connect(m_lostFinishedTimer, SIGNAL(timeout()), this, SLOT(lostFinishedHack())); 

// Start the timeout when the download data progress hits 100% 

void FtpWidget::updateXferProgress(qint64 readBytes, qint64 totalBytes) 
{ 
    m_progressBar->setValue(progress_value(readBytes, totalBytes)); 

    if (m_downloading && readBytes == totalBytes) 
     m_lostFinishedTimer->start(); 
} 

// And don't forget to stop the timer if you do get a finish: 

void FtpWidget::commandFinished(int id, bool error) 
{ 
    QFtp::Command cmd = m_ftp->currentCommand(); 
    // ... 
    if (cmd == QFtp::Get) 
    { 
     m_lostFinishedTimer->stop(); 
     //.... 
    } 
    // ... 
} 

기본적으로, 다운로드 파일을 닫고 서버를 다시 연결 한 다음 파일로 이동

void FtpWidget::lostFinishedHack() 
{ 
    if (!m_downloading) 
     return; 

    if (m_downloadFile) 
    { 
     DOUT("FtpWidget::lostFinshedHack() -- file: " << DS(m_downloadFile->fileName()) << "\n"); 
     m_downloadFile->close(); 
     delete m_downloadFile; 
     m_downloadFile = 0; 
    } 

    // just reconnect the thing 
    Connect(m_ftpServerName->text()); 

    downloadNextFile(); 
} 

오히려 더 긴 시간 제한을 사용하고 있지만 충분히 잘 작동하는 것 같습니다.

내가 그 일을 제자리에서 얻은 후에 얼마 지나지 않아 나는 QFtp 내부에서 일어나는 일을 살펴 보았다. 디버거를 사용하여 중단 점에 인쇄 명령을 추가하면에서 원시 응답을 볼 수 있습니다. 무슨 일이 벌어지고 있는지 내가 언젠가 다른 순서로 ftp 응답을 보내는 FTP 서버입니다.

이 같은 내 흔적이 보이는 작품 : 내 추적을 중단 후크했습니다 QFtp 객체의 민간 부분 인 FtpWidget::commandStartedcommandFinished 내 슬롯, 그리고 _q_piFtpReply()이다

FtpWidget::commandStarted(id: 265) -- Get 
Function: QFtpPrivate::_q_piFtpReply(int, const QString &), code: 200, text "Operation successful" 
Function: QFtpPrivate::_q_piFtpReply(int, const QString &), code: 213, text "135980" 
Function: QFtpPrivate::_q_piFtpReply(int, const QString &), code: 200, text "Operation successful" 
Function: QFtpPrivate::_q_piFtpReply(int, const QString &), code: 150, text "Opening BINARY connection for 000-23Sep2014_103527.jpg (135980 bytes)" 
Function: QFtpPrivate::_q_piFtpReply(int, const QString &), code: 226, text "Operation successful" 
FtpWidget::commandFinished(id: 265, error: 0) -- Get 

. 실패하면

내가 얻을 : 200 응답 코드가 문제가 될 것으로 보인다 후

FtpWidget::commandStarted(id: 256) -- Get 
Function: QFtpPrivate::_q_piFtpReply(int, const QString &), code: 200, text "Operation successful" 
Function: QFtpPrivate::_q_piFtpReply(int, const QString &), code: 213, text "135896" 
Function: QFtpPrivate::_q_piFtpReply(int, const QString &), code: 200, text "Operation successful" 
Function: QFtpPrivate::_q_piFtpReply(int, const QString &), code: 150, text "Opening BINARY connection for 000-23Sep2014_103525.jpg (135896 bytes)" 
FtpWidget::lostFinshedHack() 
FtpWidget::lostFinshedHack() -- file: C:/Users/sean/Temp/Snapshots5/000-23Sep2014_103525.jpg 
FtpWidget::connect("ftp://[email protected]/") 

는 150 응답 코드를 얻기. 따라서 FTP 응답 codes을 찾아 가서 qftp.cpp를 살펴보면 150이 도착한 후 150이 도착하는 것으로 보입니다. 그러면 qftp 구현 상태 시스템이 영구 대기 상태가됩니다.늘어나는만큼 내 qftp.cpp (어쩌면 내가 와이어 상어를 확인해야합니다)를 망치고 내 FTP 서버를 말할 수 있습니다.

지금은 문제에 대한 나의 타임 아웃 해결 방법을 고수하고 있습니다.

+0

입니다. 나 자신을 해킹하려고 시도했지만, 나는 충분히 신뢰할만한 것을 얻지 못했다. 실패 할 때 다시 연결하려했지만 결국 FTP 서버에서 동시에 닫을 수없는 많은 동시 연결로 종료되었습니다. 그래서 나는 나의 FTP 작업을 위해 Qt를 사용하는 것을 확실하게 포기하기로 결정했다. 나는 [FTP 클라이언트 클래스] (http://www.codeproject.com/Articles/8667/FTP-Client-Class) 대신 매우 사용하기 쉽고 신뢰할 수 있습니다. – Karalix

2

답변하기에는 너무 늦었지만 여전히 다른 사람들에게 도움이 될 수 있습니다. 마지막 명령은 get 인 경우 commandFinished() 슬롯은 다음 if (ftp->currentCommand() == QFtp::Get) 이후, 마지막 명령을 식별 할 수 없습니다 호출 될 때 void Ftp::commandFinished(int i, bool error)에서

그것도 QFtp::None 옵션을 확인하는 것이 낫다, 때문에 현재의 명령을하지 않을 수 있습니다 이미 완료되었으므로 get이됩니다.

또한 if(ftp->currentCommand() == QFtp::Get || 1 == id)

+0

답장을 보내 주셔서 감사합니다. 이제 문제가되는 코드에 액세스 할 수 없으므로 제안을 테스트 할 수 없습니다. 다른 사용자에게 도움이되기를 바랍니다. – Karalix