QFtp Get never emits commandFinished()

时间:2014-05-16 15:00:32

标签: qt ftp qftp

我目前正面临一个关于QFtp的奇怪问题。我想从FTP服务器下载一堆文件,但是当我到某个时候,在y上下载x文件后,ftp->get()命令完成,文件被填满,但是没有发出{ {1}} SIGNAL因此它不会下载其他文件。

这是我的代码:

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是否有限制我没有找到?或其他什么?

编辑:自从我发布以来,我测试了一些东西,在监视dataTransferProgress()信号时,令人震惊的是有问题的文件被完全下载(qDebug说" 88928 / 88928")但我从不输入commandFinished()。

我的插槽commandFinished()以这种方式链接到我的QFtp :: commandFinished SIGNAL:

Sleep(2000)

2 个答案:

答案 0 :(得分:3)

我看到了几乎相同的东西,我使用的FTPWidget类从未收到commandFinished的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回复。

当它工作时,我的跟踪看起来像:

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

FtpWidget::commandStartedcommandFinished是我的插槽,而_q_piFtpReply()是QFtp对象的私有部分,我挂钩了我的跟踪断点。

当它失败时,我得到:

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://root@169.254.1.180/")

在200回复​​代码之后获取150回复代码似乎是个问题。因此,如果您查找FTP回复codes并查看qftp.cpp,它看起来在150导致qftp实现状态机进入永久等待之后150到达。至于我可以告诉它我的ftp服务器搞砸事情而不是qftp.cpp(也许我应该尝试使用线鲨来确保)。

目前我正在坚持解决问题的超时解决方法。

答案 1 :(得分:2)

我来不及回复,但它仍然可以帮助别人。

void Ftp::commandFinished(int i, bool error)中,最好还检查QFtp::None选项, 因为如果你的最后一个命令是get,那么当commandFinished()槽被调用时 if (ftp->currentCommand() == QFtp::Get)将无法识别最后一个命令,因为您当前的命令可能不是get,因为它已经完成。

您也可以使用ID进行检查 作为if(ftp->currentCommand() == QFtp::Get || 1 == id)