Команда QFTP завершена отправлена ​​слишком рано

КТ версии 5.4.

Я пытаюсь загрузить все файлы из определенного каталога с помощью QFtp.

Иногда сигнал commandFinished(int, bool) отправляется слишком рано.

Я использую сигнал dataTransferProgress(qint64, qint64), чтобы проверить ход загрузки.

Когда это работает, у меня есть вывод, например:

Download 1
dataTransferProgress 0/150
dataTransferProgress 150/150
commandFinished
Dowload 2
dataTransferProgress 0/250
dataTransferProgress 250/250
commandFinished

И мои файлы в порядке

Когда это не работает, у меня есть:

Download 1
dataTransferProgress 0/150
commandFinished
Dowload 2
150/150
0/250
commandFinished

Файл 1 пустой. Файл 2 содержит данные файла 1.

Мой FTP-объект

class ActionFTP : public QFtp
{

Q_OBJECT
public:


ParamConnexion parametres;
QString FTP_export="exportX3_OFT/";
QString FTP_import="exportOFT_X3/";
QString FTP_historique="historique/";
QString OFT_export;
QString OFT_import;
QString OFT_historique;
QString ficConfig;
QFile *file;
QSettings *settings;

ActionFTP(QObject *parent = 0, QString fichierConfig = "config.ini", int detail = 0);
~ActionFTP();

bool recupFichier_X3_OFT(const QString&); // Function to download the File
bool ftpestdeconnecte(); // Check if my ftp is deconnected
void connecter(); // Connect me to the FTP
void deconnecter(); // Disconnect me from the FTP
void ContenuRepertoireFTP(); // List all the files in the FTP directory
bool getCommandEnCours(){return commandEnCours;} // Check if a command is already running
QList<QUrlInfo> getListePrete(){return listeFichiers;} // Return if the list of the 
bool commandEnCours;

private :
int idEnCours;
QList<QUrlInfo> listeFichiers;

private slots:
void slot_append(QString info); // Get some informations
void ftpCommandFinished(int id, bool err);
void ftpCommandStarted(int id);
void remplirList(QUrlInfo);
void ftpdatatransferprogress(qint64, qint64);

signals :
void signal_connexionFaite(bool); // Send when I'm connected
void signal_deconnexionFaite(bool); // Send when I'm disconnected
void signal_append(QString infos); // Send some informations
void signal_listePrete(bool); // List ready 
void fintransfertfichierrecup(); // When the get command is finished.
};

#endif // ACTIONFTP_H

.cpp

// I use a QSettings to get the different Path and the FTP Username/Login/Port/Host/TransferMode
ActionFTP::ActionFTP(QObject *parent, QString fichierConfig, int detail ) : QFtp(parent)
{
    settings = new QSettings(fichierConfig, QSettings::IniFormat);
    OFT_export=settings->value("Echange/DossierOFT").toString();
    OFT_import=settings->value("Echange/DossierX3").toString();
    OFT_historique=settings->value("Echange/DossierHistorique").toString();
    connect(this, SIGNAL(signal_append(QString)),this,SLOT(slot_append(QString)));
    connect(this, SIGNAL(commandFinished(int, bool)),this, SLOT(ftpCommandFinished(int, bool)));
    connect(this,SIGNAL(commandStarted(int)), this, SLOT(ftpCommandStarted(int)));
    connect(this, SIGNAL(listInfo(QUrlInfo)), this, SLOT(remplirList(QUrlInfo)));
    connect(this, SIGNAL(dataTransferProgress(qint64,qint64)), this, SLOT(ftpdatatransferprogress(qint64, qint64)));
    ficConfig=fichierConfig;
    majParametres();

}




void ActionFTP::ftpdatatransferprogress(qint64 un, qint64 deux){
    qDebug()<<un<<deux;
}

ActionFTP::~ActionFTP()
{

}

bool ActionFTP::recupFichier_X3_OFT(const QString &fichier){
    if(commandEnCours){ // A command is already running
        QString infos = "Une commande est déjà en cours.";
        emit signal_append(infos);
    }
    else{
     file = new QFile(OFT_import+fichier);
     if(file->exists())file->remove();

     QString infos = "Demande de r�cup�ration du fichier " + FTP_export+fichier;
     emit signal_append(infos);

     qDebug()<<"return de file->open "<<file->open(QIODevice::ReadWrite); // Always return TRUE
     get(FTP_export+fichier, file, Binary); // Get command
    }
    return true;
}



void ActionFTP::slot_append(QString info){
    qDebug()<<info;
}

bool ActionFTP::ftpestdeconnecte()
{
    if (state()==QFtp::Unconnected)
        return true;
    return false;
}



void ActionFTP::connecter() {
        setTransferMode((QFtp::TransferMode)parametres.TransfertMode);
        if(!commandEnCours)
            connectToHost(parametres.Hostname, parametres.Port);
        else{
            QString infos = "Une commande est déjà en cours.";
            emit signal_append(infos);
        }
}

void ActionFTP::deconnecter() {
    if(commandEnCours){
        QString infos = "Une commande est déjà en cours.";
        emit signal_append(infos);
    }
    else{
     close();
    }
}

void ActionFTP::remplirList(QUrlInfo t){
    listeFichiers.push_back(t);
}

void ActionFTP::ContenuRepertoireFTP(){ //Ask the list of files name in the directory
    if(commandEnCours){
        QString infos = "Une commande est déjà en cours.";
        emit signal_append(infos);
    }
    else{
        listeFichiers.clear();
        list(FTP_export);
    }
}

void ActionFTP::ftpCommandStarted(int id){
    idEnCours = id;
    commandEnCours=true;
    qDebug()<<"dans commandStarted "<<id;
}

void ActionFTP::ftpCommandFinished(int id, bool err) {
    qDebug()<<"dans ftpCommandFinished"<<id<<err;
    QString infos;
    if(err) {
        infos = QString(" Erreur lors de la commande %i de type %i").arg(id, currentCommand());
        erreurFTP(infos);
    }
    else {
        infos += " OK";
    }
    emit signal_append(infos);
    if(idEnCours==id){
        QString infos;

        switch(currentCommand()) {
        case QFtp::None :
            break;
        case QFtp::SetTransferMode :
            break;
        case QFtp::SetProxy :
            break;
        case QFtp::ConnectToHost :
            if(!err)
                login(parametres.UserName, parametres.Password);
            else
                 emit signal_connexionFaite(err);
            break;
        case QFtp::Login :
            commandEnCours = false;
            emit signal_connexionFaite(err);
            break;
        case QFtp::Close :
            commandEnCours = false; // Signifier qu'il n'y a plus de transfert en cours
            emit signal_deconnexionFaite(err);
            break;
        case QFtp::List :
            commandEnCours=false;
            emit signal_listePrete(err);
            break;
        case QFtp::Cd :
            break;
        case QFtp::Get :
            file->close();
            file = 0;
            commandEnCours = false; // Signifier qu'il n'y a plus de transfert en cours
            emit fintransfertfichierrecup();
            qDebug()<<"signal get emit";
            break;
        case QFtp::Put :
            commandEnCours = false; // Signifier qu'il n'y a plus de transfert en cours
            emit fintransfertfichierenvoi();
            break;
        case QFtp::Remove :
            commandEnCours = false;
            emit fintransfertfichiersuppr();
            break;
        case QFtp::Mkdir :
            break;
        case QFtp::Rmdir :
            break;
        case QFtp::Rename :
            break;
        case QFtp::RawCommand :
            break;
        default :
            infos = "Commande inconnue !!";
        }
        idEnCours = 0;
    }
}

Мой объект, который вызывает мой объект FTP

  class TacheEchanges : public QTimer
  {
      Q_OBJECT
  public:
  explicit TacheEchanges(QObject *parent = 0);

  signals:

  public slots:

  private slots:
  virtual void slot_check();

  protected:

  private:
  ActionFTP *ftp; // My FTP object
  QList<QUrlInfo> listDownload; // List of the files name
  int indiceDownload; // Iterator


  private slots:
  void continuerDownload();  // When one file is downloaded
  void connexionFaite(bool); // When I am connected to the FTP
  void listePrete(bool); // When my command list is done

  };

  #endif // TACHEECHANGES_H

.cpp

TacheEchanges::TacheEchanges(GestionBdD_Hizkia* bdd, QObject *parent)
    : QTimer(parent)
{

        settings =new QSettings(FICHIERCONFIG, QSettings::IniFormat);


try{

        path_fichiersreference="";
        path_poursage="";
        path_historique="";
        jobs = QList<Job>();
        ftp = new ActionFTP(this, FICHIERCONFIG);

        connect(this, SIGNAL(timeout()), this, SLOT(slot_check()));
        connect(ftp,SIGNAL(fintransfertfichierenvoi()),this,SLOT(continuerUpload()));
        connect(ftp, SIGNAL(signal_connexionFaite(bool)), this, SLOT(connexionFaite(bool)));
        connect(ftp, SIGNAL(signal_listePrete(bool)), this, SLOT(listePrete(bool)));


     //Differente path
     path_fichiersreference =settings->value("Echange/DossierX3").toString();
     path_historique =settings->value("Echange/DossierHistorique").toString();
     path_poursage=settings->value("Echange/DossierOFT").toString();
     indiceDownload=0;

  }

        catch(ErreurGeneriqueException &e) {
        desc.message = "TacheEchanges\n"+ e.what();
        desc.niveau = NIVEAU_CRITIQUE;
        InterfaceBdD::historiser(desc);
        qDebug() << desc.message;

        }

        catch(...) {
     //   QDebug() << "TacheEchanges\n" << e.get_message();


        desc.message = "TacheEchanges ERREUR INCONNUE";

        desc.niveau = NIVEAU_CRITIQUE;
        InterfaceBdD::historiser(desc);
        qDebug() << desc.message;

        }
}

// If i am connected, i try to get the list of files name
void TacheEchanges::connexionFaite(bool err){
    if(err)
        throw new ErreurGeneriqueException("Impossible de se connecter");
    else
        ftp->ContenuRepertoireFTP();
}

void TacheEchanges::slot_check()
{
        ftp->connecter();
}

// I take the list and start the download
void TacheEchanges::listePrete(bool err){ 
    if(!err){
        listDownload = ftp->getListePrete();
        continuerDownload();
    }
    else{
        throw new ErreurBasiqueException("Un problème est survenu lors de la récupération de la liste des fichiers présents sur le FTP.");
    }
}

void TacheEchanges::continuerDownload(){
    if(indiceDownload==listDownload.size()){
        indiceDownload=0;
        continuerSuppression();
        return;
    }
    else{
        ftp->recupFichier_X3_OFT(listDownload.at(indiceDownload).name());
        indiceDownload++;
    }
}

person bastien pinaquy    schedule 01.03.2016    source источник


Ответы (2)


Также посмотрите здесь разницу между активным и пассивным

person Community    schedule 02.03.2016

Хорошо, когда я пытаюсь подключиться к FTP, я использую

setTransferMode(QFtp::TransferMode);

Я использовал значение по умолчанию QFtp::Active, если поставить QFtp::Passive, то работает.

person bastien pinaquy    schedule 02.03.2016