Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. FTPClient using QTcpSocket and signals and slots
Forum Updated to NodeBB v4.3 + New Features

FTPClient using QTcpSocket and signals and slots

Scheduled Pinned Locked Moved General and Desktop
14 Posts 2 Posters 4.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    robsonQTnewbie
    wrote on last edited by
    #3

    Hi, thank you for the reply:) Infortunately I can use only QTcpSocket for this project :/ It's the requirement to pass the course ony my studies.

    Here come's my source code and a screenshot from the project so you can see what files I have.
    !http://przeklej.org/file/vlK2gP/snapshot1.png(QTCreator-snapshot)!

    MAINWINDOW.h:
    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <exitdialog.h>
    #include <QString>
    #include <QDirModel>

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void Refresh();
    QString url, login, password, port;
    private slots:
    void on_actionZako_cz_triggered();

    void on_actionKonfiguruj_triggered();
    
    void on_pushButton_clicked();
    
    void on_pushButton_3_clicked();
    
    void on_pushButton_2_clicked();
    
    void on_pushButton_5_clicked();
    

    private:
    QDirModel dirModel;
    Ui::MainWindow *ui;
    void addRoot(QString name, QString size, QString type);
    };

    #endif // MAINWINDOW_H
    @

    1 Reply Last reply
    0
    • R Offline
      R Offline
      robsonQTnewbie
      wrote on last edited by
      #4

      MAINWINDOW.cpp
      @#include "mainwindow.h"
      #include "ui_mainwindow.h"
      #include "exitdialog.h"
      #include "konfigurujdialog.h"
      #include "socketconnection.h"
      #include <QMessageBox>
      #include <stdio.h>
      #include <QRegExp>

      MainWindow::MainWindow(QWidget *parent) :
      QMainWindow(parent),
      ui(new Ui::MainWindow)
      {
      ui->setupUi(this);
      Refresh();
      }

      MainWindow::~MainWindow()
      {
      delete ui;
      }

      void MainWindow::on_actionZako_cz_triggered()
      {
      ExitDialog *exit = new ExitDialog();
      exit->setModal(true);
      exit->exec();
      }

      void MainWindow::on_actionKonfiguruj_triggered()
      {
      KonfigurujDialog *konfig = new KonfigurujDialog();
      konfig->setModal(true);
      konfig->exec();
      }

      void MainWindow::on_pushButton_clicked() //connect button
      {
      ui->textBrowser->clear();
      ui->treeWidget_2->clear();
      url = ui->urlValue->text();
      login = ui->loginValue->text();
      password = ui->passwordValue->text();
      port = ui->portValue->text();

      socketconnection *s = new socketconnection(url, login, password, port);
      QString komunikat, komunikat2;
      QString* listaFolderow;
      QString* sciezkaFolderow;
      komunikat = s->test();                 
      listaFolderow = &(s->directoryList);   // downloading the content from the public variable that's carreing the dirlisting
      sciezkaFolderow = &(s->currentPath);   // downloading the content from the public variable that's carreing the currentpath on the ftp server
      ui->textBrowser->insertPlainText(komunikat);
      
      
      QRegExp regex1("\n");
      QRegExp regex2("[ ]+|\n");
                                  
      std::string DirPath = sciezkaFolderow->toStdString();
      *sciezkaFolderow = "";
      for(int i = 0; i < DirPath.length(); i++)
      {
          int j = i+1;
          if(DirPath[i] == '\"')
          {
              while(DirPath[j] != '\"')
              {
                  *sciezkaFolderow += DirPath[j];
                  j++;
              }
              break;
          }
      }
      qDebug() << *sciezkaFolderow;
      
      ui->lineEdit_6->setText(*sciezkaFolderow);
      
      QStringList listing;                    //  lista zawierająca całe wiersze listingu plików
      listing = listaFolderow->split(regex1);
      
      std::string part;
      std::string partI, partII;
      QStringList QpartI;
      
      int i = 0, globalCounter = 0;
      foreach (QString var, listing)
          globalCounter++;
      QString czyFolder[globalCounter], Rozmiar[globalCounter], Nazwa[globalCounter];
      
      foreach (QString var, listing)
      {
         part = var.toStdString();
         int licznik = 0;
         for(int j = 0; j < part.length(); j++)
         {
             if(licznik < 55)
                 partI += part[j];
             else
             {
                 if(licznik == part.length()-1)
                     break;
                 partII += part[j];
             }
             licznik++;
         }
      
         QpartI << QString::fromStdString(partI).split(regex2);
         Nazwa[i] = QString::fromStdString(partII);
         partI = "";
         partII = "";
         i++;
      }
      QpartI.removeAll("");
      i = 0;
      int j = 0;
      foreach(QString var, QpartI)
      {
          i++;
          if(i == 1)
          {
              if(var.left(1) == "d")
                  czyFolder[j] = "Directory";
              else
                  czyFolder[j] = "File";
          }
          if(i == 5)
              Rozmiar[j] = var;
      
          if(i == 8)
          {
              i = 0;
              j++;
          }
      }
      for(i = 0; i < globalCounter; i++)
      {
          addRoot(Nazwa[i], Rozmiar[i], czyFolder[i]);
      }
      

      }

      void MainWindow::addRoot(QString name, QString size, QString type)
      {
      QTreeWidgetItem pWidgetItem = new QTreeWidgetItem(ui->treeWidget_2);
      pWidgetItem->setText(0, name);
      pWidgetItem->setText(1, size);
      pWidgetItem->setText(2, type);
      ui->treeWidget_2->addTopLevelItem(pWidgetItem);
      }
      void MainWindow::Refresh()
      {
      dirModel.setParent(this);
      dirModel.setReadOnly(false);
      QDirModel
      model = &dirModel;
      ui->treeView->setModel(model);

      model->setSorting(QDir::DirsFirst | QDir::IgnoreCase | QDir::Name);
      
      QModelIndex index = model->index("/");
      ui->treeView->expand(index);
      ui->treeView->scrollTo(index);
      ui->treeView->setCurrentIndex(index);
      ui->treeView->resizeColumnToContents(0);
      
      // geting the filepath
      
      QFileInfo informacja;
      index = ui->treeView->currentIndex();
      informacja = model->fileInfo(index);
      ui->lineEdit->setText(informacja.filePath());
      

      }

      void MainWindow::on_pushButton_3_clicked() //button do przodu sekcji KOMPUTER LOKALNY
      {
      QDirModel* model = &dirModel;
      QModelIndex index = ui->treeView->currentIndex();
      ui->treeView->expand(index);
      QFileInfo informacja = model->fileInfo(index);
      ui->lineEdit->setText(informacja.filePath());
      index = ui->treeView->indexBelow(ui->treeView->currentIndex());

      ui->treeView->setCurrentIndex(index);
      

      }

      void MainWindow::on_pushButton_2_clicked() //button cofnij sekcji KOMPUTER LOKALNY
      {
      QDirModel* model = &dirModel;
      ui->treeView->collapse(ui->treeView->currentIndex());
      QModelIndex index = ui->treeView->indexAbove(ui->treeView->currentIndex());
      // QModelIndex index = ui->treeView->indexAbove(ui->treeView->currentIndex());

      ui->treeView->setCurrentIndex(index);
      QFileInfo informacja = model->fileInfo(index);
      ui->lineEdit->setText(informacja.filePath());
      

      }

      void MainWindow::on_pushButton_5_clicked() //butto do przodu sekcji SERWER
      {

      }
      @

      1 Reply Last reply
      0
      • R Offline
        R Offline
        robsonQTnewbie
        wrote on last edited by
        #5

        SOCKETCONNECTION.h
        @#ifndef SOCKETCONNECTION_H
        #define SOCKETCONNECTION_H

        #include <QMainWindow>
        #include <QObject>
        #include <iostream>
        #include <QTcpSocket>
        #include <QAbstractSocket>
        #include <QString>

        class socketconnection : public QObject
        {
        Q_OBJECT
        public:
        explicit socketconnection(QString url, QString login, QString password, QString port, QObject *parent = 0);
        QString test();
        QString komunikat, message, command;
        QString url, login, password, port;
        QString directoryList; //pointer to the downloaded directory listing
        QString currentPath;
        signals:

        public slots:
        void connected();
        private:
        QTcpSocket *socket;
        QTcpSocket socketTransmit;
        };

        #endif // SOCKETCONNECTION_H
        @

        1 Reply Last reply
        0
        • R Offline
          R Offline
          robsonQTnewbie
          wrote on last edited by
          #6

          SOCKETCONNECTION.cpp
          @#include "socketconnection.h"
          #include "mainwindow.h"
          #include <stdio.h>
          socketconnection::socketconnection(QString url, QString login, QString password, QString port, QObject *parent) :
          QObject(parent)
          {
          this->url = url;
          this->login = login;
          this->password = password;
          this->port = port;
          }
          QString socketconnection::test(){
          komunikat = "Status: ";
          socket = new QTcpSocket(this);
          connect(socket, SIGNAL(connected()), this, SLOT(connected()));
          komunikat += "Łączenie do serwera FTP...\n";
          socket->connectToHost((url.toUtf8().constData()), port.toShort());
          if(!socket->waitForConnected(3000)){
          komunikat += "Message: ";
          komunikat += "Przekroczony limit czasu...\n";
          }
          return komunikat;
          }
          void socketconnection::connected()
          {
          QString adresIP, transfer_port;
          std::string passive_connection = "";
          std::string oktet[6];
          int licznik = 0, portA, portB, portC;
          komunikat += "Message: ";
          while(message.length() == 0) message = socket->readLine();
          komunikat += message;
          komunikat += "Polecenie: ";
          message = "";
          command = "USER " + login + "\r\n";
          komunikat += "Polecenie: ";
          komunikat += command;
          socket->write(command.toUtf8().constData());
          socket->waitForBytesWritten(5000);
          while(message.length() == 0) message = socket->readLine();
          komunikat += "Message: ";
          komunikat += message;
          message = "";
          command = "PASS " + password + "\r\n";
          komunikat += "Polecenie: PASS <nie pokażę Ci hasła>\n";
          socket->write(command.toUtf8().constData());
          socket->waitForBytesWritten(5000);
          while(message.length() == 0) message = socket->readLine();
          komunikat += "Message: ";
          komunikat += message;
          message = "";
          command = "OPTS UTF8 ON\r\n";
          komunikat += "Polecenie: ";
          komunikat += command;
          socket->write(command.toUtf8().constData());
          socket->waitForBytesWritten(5000);
          while(message.length() == 0) message = socket->readLine();
          komunikat += "Message: ";
          komunikat += message;
          message = "";
          komunikat += "Status: Connected succesfully. Now I'm checking the directory list...\n";
          command = "TYPE I\r\n";
          komunikat += "Polecenie: ";
          komunikat += command;
          socket->write(command.toUtf8().constData());
          socket->waitForBytesWritten(5000);
          while(message.length() == 0) message = socket->readLine();
          komunikat += "Message: ";
          komunikat += message;
          message = "";
          command = "PWD \r\n";
          komunikat += "Polecenie: ";
          komunikat += command;
          socket->write(command.toUtf8().constData());
          socket->waitForBytesWritten(5000);
          int i = 0;
          while(message.length() == 0){
          message = socket->readLine();
          }
          currentPath = message;
          komunikat += "Message: ";
          komunikat += message;
          message = "";
          command = "PASV \r\n";
          komunikat += "Polecenie: ";
          komunikat += command;
          socket->write(command.toUtf8().constData());
          socket->waitForBytesWritten(5000);
          while(message.length() == 0) message = socket->readLine();
          komunikat += "Message: ";
          komunikat += message;
          passive_connection = message.toUtf8().constData();
          message = "";
          for(int i = 3; i < passive_connection.length()-2; i++){
          if(passive_connection[i] >= '0' && passive_connection[i] <= '9'){
          oktet[licznik] += passive_connection[i];
          if(passive_connection[i+1] == ',')
          {
          licznik++;
          continue;
          }
          }
          }
          adresIP = QString::fromStdString(oktet[0]) + "." + QString::fromStdString(oktet[1]) + "." + QString::fromStdString(oktet[2])
          + "." + QString::fromStdString(oktet[3]);
          portA = QString::fromStdString(oktet[4]).toInt();
          portB = QString::fromStdString(oktet[5]).toInt();
          portC = (portA * 256 + portB);
          transfer_port.setNum(portC);
          komunikat += "Tworzę połączenie na następujący adres i port: \n";
          komunikat += "Adres: " + adresIP + "\n";
          komunikat += "Port: " + transfer_port + "\n";

              socketTransmit.connectToHost(adresIP, portC);
              socketTransmit.waitForConnected(2000);
              komunikat += "Polecenie: ";
              command = "LIST \r\n";
              komunikat += command;
              socket->write(command.toUtf8().constData());
              socket->waitForBytesWritten(5000);              
              socketTransmit.waitForBytesWritten(5000);
              socketTransmit.waitForReadyRead(5000);
              socket->waitForBytesWritten(5000);
          
              socket->waitForBytesWritten(5000);
              message = socket->readLine();  //czekamy na odpowiedź kolejną z socketu poleceń
              komunikat += "Message: ";
              komunikat += message;
              message = "";
          
              message = socketTransmit.readAll();
              directoryList = message;    //  pobieramy do zmiennej directoryList listing plików i folderów
              if (directoryList != ""){
                  komunikat += "Listing plików i folderów przesłąny z powodzeniem!!!:\n";
              }
              else
                  komunikat += "Błąd! Nie udało mi się pobrać listy plików i folderów!!!\n";
              //komunikat += message;
              message = "";
              i = 0;
              while(message.length() == 0){
                  i++;
                  message = socket->readLine();
                  if(i == 32768)
                  {
                      message = "Błąd podczas transmisji polecenia";
                      break;
                  }
              }
              komunikat += "Message: ";
              komunikat += message;
              message = "";
          }
          

          @

          1 Reply Last reply
          0
          • R Offline
            R Offline
            robsonQTnewbie
            wrote on last edited by
            #7

            I know my code isn't nice but I've just started my QT experience, so I hope that you'll understand and can help me. Thanks a lot :)

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #8

              There are indeed several things that I don't follow:

              • Why are you mixing std::string and QString ? Currently it just complicates your code without any benefits
              • Why are you using pointers to QString ?

              You are also creating memory leaks with your custom dialogs.

              Anyway, for your original problem. You are doing everything in the connected slot, which is a bad idea. You need to refactor that and split the logic for the various commands you want to send in their own functions

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • R Offline
                R Offline
                robsonQTnewbie
                wrote on last edited by
                #9

                I'm mixing QString with std::string because I couldn't filter the QString like a simple array, so I decided to go on the easiest way and parse it to std::string.

                I need pointers to QString because I have no idea how get access to one variable from one class in another class. I think pointers are a good method to get the content from variables....

                Which custom dialogs do you mean? I thinked about your advice to split to signal and slot system but I have trouble with it..... now i have something like that:
                @#include "mainwindow.h"
                #include "ui_mainwindow.h"

                MainWindow::MainWindow(QWidget *parent) :
                QMainWindow(parent),
                ui(new Ui::MainWindow)
                {
                ui->setupUi(this);
                }

                MainWindow::~MainWindow()
                {
                delete ui;
                }

                void MainWindow::on_pushButton_clicked() // connect Button
                {
                commandSocket = new QTcpSocket(this);

                login = ui->loginValue->text();
                url = ui->urlValue->text();
                password = ui->passwordValue->text();
                port = ui->portValue->text();
                qint64 timeout = 4000;
                
                connect(commandSocket, SIGNAL(connected()), this, SLOT(connected()));
                connect(commandSocket, SIGNAL(bytesWritten(timeout)), this, SLOT(getMessage()));
                qDebug() << "Connecting...";
                
                commandSocket->connectToHost(url, port.toShort());
                if(!commandSocket->waitForConnected(3000)){
                    qDebug() << "Przekroczony limit czasu...\n";
                }
                

                }

                void MainWindow::connected()
                {
                qDebug() << "In connected()...";
                sendMessage("USER ", login);

                }
                void MainWindow::sendMessage(QString message, QString argument)
                {
                qDebug() << "in sendMessage...";
                QString displayedArgument, command;
                if(message == "PASS ")
                displayedArgument = "SECRET_PASSWORD...";
                else
                displayedArgument = argument;
                command = message + argument + "\r\n";
                commandSocket->write(command.toUtf8().constData());
                commandSocket->waitForBytesWritten(10000);

                ui->textBrowser->setOverwriteMode(false);
                ui->textBrowser->setText("Polecenie: " + message + displayedArgument + "\n");
                qDebug() << "send message done...";
                

                }
                void MainWindow::getMessage()
                {
                qDebug() << "In getMessage()...";
                QString message = "";
                //while(message == "")
                message = commandSocket->readLine();

                qDebug() << message;
                ui->textBrowser->setOverwriteMode(false);
                ui->textBrowser->setText(message);
                

                }@
                and unfortunately it's not working:/
                PS. I decidet to put everything in the mainwindow.cpp.

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #10

                  What do you mean by "can't filter like a simple array" ?

                  You should have a look at the fortune client/server example for inspiration

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • R Offline
                    R Offline
                    robsonQTnewbie
                    wrote on last edited by
                    #11

                    I mean something like that:
                    @
                    QString someQString = "I like Qt!", outputQString = "";
                    for(int i = 0; i < someQString.length(); i++)
                    {
                    if(someQString[i] != " ")
                    outputString += someQString[i];
                    }
                    @

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #12

                      You want to remove all white spaces in the string ?
                      From the top of my head:
                      @
                      someQString.replace(QRegular[removed]"\s"), "");
                      @

                      Replace QRegularExpression by QRegExp if you are on Qt 4

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      0
                      • R Offline
                        R Offline
                        robsonQTnewbie
                        wrote on last edited by
                        #13

                        Thanks:) I moved forward with my project and now i need help with downloading files. The problem is that, when I download a file (first .txt) the data go on the socket but not everything. When i download a small file it works fine, but when I download a bigger file it looses data. :/ Do you have a advice form me?

                        P.S. I start the download from the transfer socket, when on the commandLineSocket is the command RETR succesfully transmited.

                        1 Reply Last reply
                        0
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #14

                          Look at readyRead and the asynchronousness handling of IO devices

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved