Important: Please read the Qt Code of Conduct -

QStateMachine/Networking best practice

  • Hi,
    I want to design a ftp client. FTP is specified in rfc959. Sending ftp-commands and receiving the reply-codes use state machines.

    My state machine (QStateMachine) is running in the QApplication main thread. There are four states:

    • sendCommand
    • waitForReply
    • Success
    • Error

    In the socket (QTcpSocket) i'm using signals and slots.

    In the state "waitForReply" i have to wait until response is ready to read in the socket. What would be the best practice to realize this. Should i use threads in combination with waitconditions? Or is there a simple solution without an extra thread? My goal is to keep it event triggered.

    Thank you

  • Do you need to build it manually? QNetworkAccessManager can manage FTP already out of the box

  • @VRonin

    Thank you for the response. In this case I could use QNetworkAccessManager. In another project I will need a communication channel with customized port/protocol. Could I also use QNetworkAccessManager?

    Thank you

  • Lifetime Qt Champion


    Yes you can, but why do you want to make something extra complex ? You already have a state machine. What else are you thinking about ?

  • Hi,
    i'm not very used in doing cpp application. I did some C-Project using MicroC/OS-II. Always close to the hardware. It's also my first project with QT. For that reason i don't know which class will fit best for my application.

    But in this case i will try it with QtNetworkManager.

    Thank you

  • @SGaist

    I'm trying to download a file from the ftp server. This is my code:

    void downloader::doDownload()
        manager = new QNetworkAccessManager(this);
        connect(manager, SIGNAL(finished(QNetworkReply*)),
                this, SLOT(replyFinished(QNetworkReply*)));
        url = new QUrl;

    I get the following error from ftp server:

    "Error while downloading ftp://admin:admin@ Command not implemented."

    By checking with wireshark I can see the following commands:

    Response: 220 lwIP FTP Server ready.
    Request: USER admin
    Response: 331 User name okay, need password.
    Request: PASS admin
    Response: 230 User logged in, proceed.
    Request: HELP
    Response: 502 Command not implemented.
    Request QUIT
    Respoonse: 221 Goodbye.

    How can I send custom requests like QNetworkAccessManager::sendCustomRequest? But this feature is currently available for HTTP(S) only.

    Thank you

  • Lifetime Qt Champion

    What port is your ftp server listening on ?

    By the way, you should not allocate QUrl on the heap, you currently have a memory leak.

  • @SGaist
    Thank you for your response. I realy appreciate that.

    The servers control channel is listening at port 21. The Servers data channel port is unknown until data are requested. Then the servers tells which port the client should use for data connection.

    Thank you

  • Lifetime Qt Champion

    Then shouldn't you set the port to 21 in your url ?

  • @SGaist
    ... i will tray it. In my opinion it won't solve the problem. In the wireshark log I could see that the port is 21. By defining url->setSheme to "ftp" the port is defined because ftp uses Port 21 as control channel. You can also see that a communication could be established. Otherwise USER and PASS would not be accepted. I think the problem is, that the manager->get(QNetworkRequest(QUrl(*url))) follows a fixed structure.

    1. USER
    2. PASS
    3. HELP (To get all the possible commands which are implemted at the server side. If HELP is not implemented the connection will be closed. According to rfc959 (chapter 5.1) the minimum implementation does not demand HELP.

    I konw the command sequence to download the file "exp00ded.csv. But i don't know how to send single commands.

    Thank you.

  • Hi,
    Also by setting url->port to 21 it beaves the same way like without setting the port to 21. Any other idea?

    Thank you

Log in to reply