Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Staring Qt network programming
QtWS25 Last Chance

Staring Qt network programming

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
19 Posts 3 Posters 599 Views
  • 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.
  • Q Offline
    Q Offline
    qcoderpro
    wrote on last edited by
    #1

    Hi all,

    finally I could work out the issues dealing with my projects to do their jobs properly, and now they work as expected! :)

    The job/purpose: The server app shows IP address plus a port number and a label on its UI. On the other side, the client app uses those IP and port number to connect to the server and then sends it messages using a Send button on its UI.
    I may have a couple of questions to be sure I've figured out all the things related to the projects appropriately, but for this post there's merely a question: How good the projects are written to you? Which part would you add/remove/change if you were to program the projects for the purpose mentioned above, please?
    client.h:

    #include <QDataStream>
    #include <QObject>
    
    class QTcpSocket;
    
    class Client : public QObject
    {
        Q_OBJECT
    
    public:
        explicit Client(QObject *parent = nullptr);
    
    public slots:
        void sendAddress(QString, QString);
        void sendMessage(const QString&);
    
    private:
        QTcpSocket* tcpSocket { nullptr };
        QDataStream out;
    };
    

    client.cpp:

    #include "client.h"
    #include <QtNetwork>
    
    Client::Client(QObject *parent)
        : QObject{parent}
        , tcpSocket(new QTcpSocket(this)) { }
    
    void Client::sendAddress(QString ip, QString port)
    {
        tcpSocket->abort();
        tcpSocket->connectToHost(ip, port.toInt());
    }
    
    void Client::sendMessage(const QString& message) {
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
        out.setDevice(tcpSocket);
        out.setVersion(QDataStream::Qt_5_10);
        out << message;
        tcpSocket->write(block);
    }
    

    client's qml file:

     ColumnLayout {
            anchors.fill: parent
    
            TextField { id: ipAddrs; placeholderText: qsTr("IP Address ...") }
            TextField { id: portNum; placeholderText: qsTr("Port Number ...") }
    
            RowLayout {
                TextField {
                    id: txtField
                    Layout.fillWidth: true
                }
                Button {
                    text: qsTr("Send")
                    onClicked: {
                        myObj.sendAddress(ipAddrs.text.toString(), portNum.text.toString())
                        myObj.sendMessage(txtField.text)
                    }
                }
            }
        }
    
        MyClass {
            id: myObj
        }
    

    server.h:

    #include <QObject>
    #include <QAbstractSocket>
    
    class QTcpServer;
    class QTcpSocket;
    
    class Server : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QString message READ getMessage WRITE setMessage NOTIFY messageChanged)
    
    public:
        explicit Server(QObject *parent = nullptr);
    
    public slots:
        QString initServer();
        void onNewConnection();
        void writeMessage();
        void setMessage(const QString&);
        QString getMessage() const;
        void displayError(QAbstractSocket::SocketError);
    
    signals:
        void messageChanged(QString);
    
    private:
        QTcpServer* tcpServer { nullptr };
        QTcpSocket* tcpSocket { nullptr };
        QDataStream in;
        QString message;
    };
    

    server.cpp:

    #include "server.h"
    #include <QtNetwork>
    #include <QtCore>
    
    Server::Server(QObject *parent) : QObject{parent}
      , tcpServer(new QTcpServer(this))
      , tcpSocket(new QTcpSocket(this)) { }
    
    QString Server::initServer() {
    
        tcpServer = new QTcpServer(this);
        if(!tcpServer->listen())
            return "Server Unable to start the server: " +
                    tcpServer->errorString();
    
        connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection);
        connect(tcpSocket, &QAbstractSocket::errorOccurred, this, &Server::displayError);
    
        QString ipAddress;
        QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
    
        // use the first non-local IPv4 address
        for(int i=0; i<ipAddressesList.size(); ++i)
            if(ipAddressesList.at(i) != QHostAddress::LocalHost &&
                    ipAddressesList.at(i).toIPv4Address()) {
                ipAddress = ipAddressesList.at(i).toString();
                break;
            }
    
        // if we did not find one, use IPv4 localhost
        if(ipAddress.isEmpty())
            ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
    
        return " The server is running on\n\n IP: " +
                ipAddress + "\n port: " + QString::number(tcpServer->serverPort())
                + "\n\n Run the Client example now.";
    }
    
    void Server::onNewConnection()
    {
        QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
        connect(clientConnection, &QAbstractSocket::disconnected,
                clientConnection, &QObject::deleteLater);
        in.setDevice(clientConnection);
        in.setVersion(QDataStream::Qt_4_0);
        connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::writeMessage);
    }
    
    void Server::displayError(QAbstractSocket::SocketError socketError)
    {
        // for this stage, printing the error messages using qDenug will be fine
    
        switch (socketError) {
        case QAbstractSocket::RemoteHostClosedError:
            break;
        case QAbstractSocket::HostNotFoundError:
            qDebug() <<"The host was not found. Please check the "
                       "host name and port settings.";
            break;
        case QAbstractSocket::ConnectionRefusedError:
            qDebug() << "The connection was refused by the peer. "
                        "Make sure the server is running, "
                        "and check that the host name and port "
                        "settings are correct.";
            break;
        default:
            qDebug() << "The following error occurred: " + tcpSocket->errorString();
        }
    }
    
    void Server::writeMessage()
    {
        in.startTransaction();
    
        QString msg;
        in >> msg;
    
        if (!in.commitTransaction())
            setMessage("commitTransaction error");
        else
            setMessage(msg);
    }
    
    QString Server::getMessage() const
    {
        return message;
    }
    
    void Server::setMessage(const QString& newMessage)
    {
        message = newMessage;
        emit messageChanged(message);
    }
    

    server's qml file:

    ColumnLayout {
            anchors.fill: parent
            Label { text: myObj.initServer() }
            Label { text: myObj.message }
        }
    
        MyClass { id: myObj }
    

    Thanks so much in advance.

    1 Reply Last reply
    0
    • Q Offline
      Q Offline
      qcoderpro
      wrote on last edited by
      #2
      This post is deleted!
      1 Reply Last reply
      0
      • J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on last edited by
        #3

        @qcoderpro said in Staring Qt network programming:

        How good the projects are written to you

        well thats obviously very subjective, but I find nothing to critic, except naming/registering both your client and server instance MyClass. I assume they are different projects ? But it is bound to cause confusion anyway :D


        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        Q 1 Reply Last reply
        1
        • J.HilkJ J.Hilk

          @qcoderpro said in Staring Qt network programming:

          How good the projects are written to you

          well thats obviously very subjective, but I find nothing to critic, except naming/registering both your client and server instance MyClass. I assume they are different projects ? But it is bound to cause confusion anyway :D

          Q Offline
          Q Offline
          qcoderpro
          wrote on last edited by
          #4

          @J-Hilk
          Sure, I will change the name of class objects within them, thanks.
          I thought some part of code is probably redundant.

          J.HilkJ 1 Reply Last reply
          0
          • Q qcoderpro

            @J-Hilk
            Sure, I will change the name of class objects within them, thanks.
            I thought some part of code is probably redundant.

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #5

            @qcoderpro said in Staring Qt network programming:

            I thought some part of code is probably redundant

            like the tcpSocket of your Server class ? yes, true


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            Q 1 Reply Last reply
            1
            • J.HilkJ J.Hilk

              @qcoderpro said in Staring Qt network programming:

              I thought some part of code is probably redundant

              like the tcpSocket of your Server class ? yes, true

              Q Offline
              Q Offline
              qcoderpro
              wrote on last edited by
              #6

              @J-Hilk

              It's used here:
              connect(tcpSocket, &QAbstractSocket::errorOccurred, this, &Server::displayError); for displaying the errors. I don't think it'd be possible by using the tcpServer only. Disagree?

              jsulmJ J.HilkJ 2 Replies Last reply
              0
              • Q qcoderpro

                @J-Hilk

                It's used here:
                connect(tcpSocket, &QAbstractSocket::errorOccurred, this, &Server::displayError); for displaying the errors. I don't think it'd be possible by using the tcpServer only. Disagree?

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @qcoderpro But where are you doing anything with this socket?!
                The fact that you connect one signal from that socket to a slot does not mean that this socket is doing manythig useful...
                You get the socket from tcpServer->nextPendingConnection(), so why do you need tcpSocket?

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                Q 1 Reply Last reply
                2
                • Q qcoderpro

                  @J-Hilk

                  It's used here:
                  connect(tcpSocket, &QAbstractSocket::errorOccurred, this, &Server::displayError); for displaying the errors. I don't think it'd be possible by using the tcpServer only. Disagree?

                  J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote on last edited by
                  #8

                  @qcoderpro said in Staring Qt network programming:

                  Disagree

                  in principle, no I do not disagree. Listing to the error Signal of your socket is a good thing :D

                  but, you're neither sending nor receiving data with that socket. That is all done, like @jsulm said,
                  here:

                  void Server::onNewConnection()
                  {
                      QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
                      connect(clientConnection, &QAbstractSocket::disconnected,
                              clientConnection, &QObject::deleteLater);
                      in.setDevice(clientConnection);
                      in.setVersion(QDataStream::Qt_4_0);
                      connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::writeMessage);
                  }
                  

                  That socket is correctly cleaned up thumbs up but you're not listening to the error signal :D


                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  1 Reply Last reply
                  1
                  • jsulmJ jsulm

                    @qcoderpro But where are you doing anything with this socket?!
                    The fact that you connect one signal from that socket to a slot does not mean that this socket is doing manythig useful...
                    You get the socket from tcpServer->nextPendingConnection(), so why do you need tcpSocket?

                    Q Offline
                    Q Offline
                    qcoderpro
                    wrote on last edited by qcoderpro
                    #9

                    @jsulm @J-Hilk
                    I didn't know that since I'm very new to network programming. So you mean to remove the tcpSocket and that connect() from the server app and call the displayError slot this way?

                    void Server::onNewConnection()
                    {
                        QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
                       connect(clientConnection , &QAbstractSocket::errorOccurred, this, &Server::displayError);
                        connect(clientConnection, &QAbstractSocket::disconnected,
                                clientConnection, &QObject::deleteLater);
                        in.setDevice(clientConnection);
                        in.setVersion(QDataStream::Qt_4_0);
                        connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::writeMessage);
                    }
                    
                    J.HilkJ 1 Reply Last reply
                    0
                    • Q qcoderpro

                      @jsulm @J-Hilk
                      I didn't know that since I'm very new to network programming. So you mean to remove the tcpSocket and that connect() from the server app and call the displayError slot this way?

                      void Server::onNewConnection()
                      {
                          QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
                         connect(clientConnection , &QAbstractSocket::errorOccurred, this, &Server::displayError);
                          connect(clientConnection, &QAbstractSocket::disconnected,
                                  clientConnection, &QObject::deleteLater);
                          in.setDevice(clientConnection);
                          in.setVersion(QDataStream::Qt_4_0);
                          connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::writeMessage);
                      }
                      
                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on last edited by
                      #10

                      @qcoderpro said in Staring Qt network programming:

                      I didn't know that since I'm very new to network programming. So you mean to remove the tcpSocket and that connect() from the server app and call the displayError slot this way?

                      yes, or, if you want to keep a pointer to the socket as a class member variable, you could do:

                      void Server::onNewConnection()
                      {
                         if(tcpSocket)
                           //Some warning or other error handling, because old connection is still in use!
                          return;
                      
                          tcpSocket = tcpServer->nextPendingConnection();
                         connect(tcpSocket , &QAbstractSocket::errorOccurred, this, &Server::displayError);
                          connect(tcpSocket, &QAbstractSocket::disconnected,
                                  tcpSocket, [=] () ->void{
                          //A Lambda, so we can also reset the pointer to nullptr
                          tcpSocket->deleteLater();
                          tcpSocket = nullptr;
                      });
                          in.setDevice(tcpSocket);
                          in.setVersion(QDataStream::Qt_4_0);
                          connect(tcpSocket, &QAbstractSocket::readyRead, this, &Server::writeMessage);
                      }
                      

                      you would still have to remove the new QTcpSocket from your constructor and initialise tcpSocket as nullptr for this to work.


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      Q 1 Reply Last reply
                      1
                      • J.HilkJ J.Hilk

                        @qcoderpro said in Staring Qt network programming:

                        I didn't know that since I'm very new to network programming. So you mean to remove the tcpSocket and that connect() from the server app and call the displayError slot this way?

                        yes, or, if you want to keep a pointer to the socket as a class member variable, you could do:

                        void Server::onNewConnection()
                        {
                           if(tcpSocket)
                             //Some warning or other error handling, because old connection is still in use!
                            return;
                        
                            tcpSocket = tcpServer->nextPendingConnection();
                           connect(tcpSocket , &QAbstractSocket::errorOccurred, this, &Server::displayError);
                            connect(tcpSocket, &QAbstractSocket::disconnected,
                                    tcpSocket, [=] () ->void{
                            //A Lambda, so we can also reset the pointer to nullptr
                            tcpSocket->deleteLater();
                            tcpSocket = nullptr;
                        });
                            in.setDevice(tcpSocket);
                            in.setVersion(QDataStream::Qt_4_0);
                            connect(tcpSocket, &QAbstractSocket::readyRead, this, &Server::writeMessage);
                        }
                        

                        you would still have to remove the new QTcpSocket from your constructor and initialise tcpSocket as nullptr for this to work.

                        Q Offline
                        Q Offline
                        qcoderpro
                        wrote on last edited by
                        #11

                        @J-Hilk

                        Since, as stated earlier, I'm very new to network programming, let me please start from beginning to figure out the things properly and be sure about that.
                        Let's start from the server app. In server.cpp starting from top, we have tcpServer(new QTcpServer(this)) { }.
                        Here tcpSever is an object whose job is to listen to incoming connections (tcpSockets) and accept one or a number of them. We initialize it and pass the program/project's pointer (this) to it as the parent.
                        Next in:

                         //   tcpServer = new QTcpServer(this);
                            if(!tcpServer->listen())
                                return "Server Unable to start the server: " +
                                        tcpServer->errorString();
                        
                            connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection);
                        

                        we probably can remove the first line which is repetitive! Then the tcpServer will listen on all network interfaces for incoming connections/tcpSockets (IP + port number) and returns an error if it fails listening.
                        If a connection arrives, connect() invokes the onNewConnection slot.
                        Completely right up to this point, please?

                        J.HilkJ 1 Reply Last reply
                        0
                        • Q qcoderpro

                          @J-Hilk

                          Since, as stated earlier, I'm very new to network programming, let me please start from beginning to figure out the things properly and be sure about that.
                          Let's start from the server app. In server.cpp starting from top, we have tcpServer(new QTcpServer(this)) { }.
                          Here tcpSever is an object whose job is to listen to incoming connections (tcpSockets) and accept one or a number of them. We initialize it and pass the program/project's pointer (this) to it as the parent.
                          Next in:

                           //   tcpServer = new QTcpServer(this);
                              if(!tcpServer->listen())
                                  return "Server Unable to start the server: " +
                                          tcpServer->errorString();
                          
                              connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection);
                          

                          we probably can remove the first line which is repetitive! Then the tcpServer will listen on all network interfaces for incoming connections/tcpSockets (IP + port number) and returns an error if it fails listening.
                          If a connection arrives, connect() invokes the onNewConnection slot.
                          Completely right up to this point, please?

                          J.HilkJ Offline
                          J.HilkJ Offline
                          J.Hilk
                          Moderators
                          wrote on last edited by
                          #12

                          @qcoderpro said in Staring Qt network programming:

                          Completely right up to this point, please?

                          yes,

                          see I didn't even notice the 2nd QTcpServer instance, the problem if you just "scroll" through it :D


                          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                          Q: What's that?
                          A: It's blue light.
                          Q: What does it do?
                          A: It turns blue.

                          Q 1 Reply Last reply
                          2
                          • J.HilkJ J.Hilk

                            @qcoderpro said in Staring Qt network programming:

                            Completely right up to this point, please?

                            yes,

                            see I didn't even notice the 2nd QTcpServer instance, the problem if you just "scroll" through it :D

                            Q Offline
                            Q Offline
                            qcoderpro
                            wrote on last edited by
                            #13

                            @J-Hilk

                            see I didn't even notice the 2nd QTcpServer instance, the problem if you just "scroll" through it :D

                            Yeah, no problem, thanks for your kindness. :)
                            Moving on, we reach this slot:

                            void Server::onNewConnection()
                            {
                                QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
                                connect(clientConnection, &QAbstractSocket::errorOccurred, this, &Server::displayError);
                                connect(clientConnection, &QAbstractSocket::disconnected,
                                        clientConnection, &QObject::deleteLater);
                                in.setDevice(clientConnection);
                                in.setVersion(QDataStream::Qt_4_0);
                                connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::writeMessage);
                            }
                            

                            in which we have clientConnection that is a QTcpSocket representing the server side of the connection!

                            1. But I assume that clientConnection is the one we have already sent from the client app to this server's connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection); and caused the above slot to be invoked! I believe we don't need two tcpSockets, one already sent to the server and another created inside the server the way above! Agree?
                            2. In the next connect(), we call the displayError in case of any connection error. Connection errors may happen due to the Internet, operating system or the hardware failures. Using QAbstractSocket::errorOccurred we try to catch and then show them to the user. Right?
                            3. Using the second connect() in the slot above, we aim to delete the clientConnection when we later on exit the slot! But this is ambiguous! If the clientConnection was the one we already sent from the client app, why should we delete it when we exit the slot (onNewConnection)? So something in my assumptions should not be correct!
                            jsulmJ J.HilkJ 2 Replies Last reply
                            0
                            • Q qcoderpro

                              @J-Hilk

                              see I didn't even notice the 2nd QTcpServer instance, the problem if you just "scroll" through it :D

                              Yeah, no problem, thanks for your kindness. :)
                              Moving on, we reach this slot:

                              void Server::onNewConnection()
                              {
                                  QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
                                  connect(clientConnection, &QAbstractSocket::errorOccurred, this, &Server::displayError);
                                  connect(clientConnection, &QAbstractSocket::disconnected,
                                          clientConnection, &QObject::deleteLater);
                                  in.setDevice(clientConnection);
                                  in.setVersion(QDataStream::Qt_4_0);
                                  connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::writeMessage);
                              }
                              

                              in which we have clientConnection that is a QTcpSocket representing the server side of the connection!

                              1. But I assume that clientConnection is the one we have already sent from the client app to this server's connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection); and caused the above slot to be invoked! I believe we don't need two tcpSockets, one already sent to the server and another created inside the server the way above! Agree?
                              2. In the next connect(), we call the displayError in case of any connection error. Connection errors may happen due to the Internet, operating system or the hardware failures. Using QAbstractSocket::errorOccurred we try to catch and then show them to the user. Right?
                              3. Using the second connect() in the slot above, we aim to delete the clientConnection when we later on exit the slot! But this is ambiguous! If the clientConnection was the one we already sent from the client app, why should we delete it when we exit the slot (onNewConnection)? So something in my assumptions should not be correct!
                              jsulmJ Offline
                              jsulmJ Offline
                              jsulm
                              Lifetime Qt Champion
                              wrote on last edited by jsulm
                              #14

                              @qcoderpro said in Staring Qt network programming:

                              one already sent to the server and another created inside the server

                              1. Sockets are not send to anywhere. You have one socket on the client side and one on the server side and both communicate with each other. The socket on the server side is the one you get using tcpServer->nextPendingConnection(). These two sockets are two different objects living in two different processes (and usually on different machines)!
                              2. Yes
                              3. As said in 1.: sockets are not send to anywhere!

                              https://forum.qt.io/topic/113070/qt-code-of-conduct

                              1 Reply Last reply
                              2
                              • Q qcoderpro

                                @J-Hilk

                                see I didn't even notice the 2nd QTcpServer instance, the problem if you just "scroll" through it :D

                                Yeah, no problem, thanks for your kindness. :)
                                Moving on, we reach this slot:

                                void Server::onNewConnection()
                                {
                                    QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
                                    connect(clientConnection, &QAbstractSocket::errorOccurred, this, &Server::displayError);
                                    connect(clientConnection, &QAbstractSocket::disconnected,
                                            clientConnection, &QObject::deleteLater);
                                    in.setDevice(clientConnection);
                                    in.setVersion(QDataStream::Qt_4_0);
                                    connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::writeMessage);
                                }
                                

                                in which we have clientConnection that is a QTcpSocket representing the server side of the connection!

                                1. But I assume that clientConnection is the one we have already sent from the client app to this server's connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection); and caused the above slot to be invoked! I believe we don't need two tcpSockets, one already sent to the server and another created inside the server the way above! Agree?
                                2. In the next connect(), we call the displayError in case of any connection error. Connection errors may happen due to the Internet, operating system or the hardware failures. Using QAbstractSocket::errorOccurred we try to catch and then show them to the user. Right?
                                3. Using the second connect() in the slot above, we aim to delete the clientConnection when we later on exit the slot! But this is ambiguous! If the clientConnection was the one we already sent from the client app, why should we delete it when we exit the slot (onNewConnection)? So something in my assumptions should not be correct!
                                J.HilkJ Offline
                                J.HilkJ Offline
                                J.Hilk
                                Moderators
                                wrote on last edited by
                                #15

                                @qcoderpro

                                Yeah, no problem, thanks for your kindness. :)

                                no problem I think we have a very pleasant conversation/exchange, I like it :D

                                1But I assume that clientConnection is the one we have already sent from the client app to this server's connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection); and caused the above slot to be invoked! I believe we don't need two tcpSockets, one already sent to the server and another created inside the server the way above! Agree?

                                I'm not sure what you mean, you're not literally sending a socket via the network ? You're creating one on the server side and one on the client side and those communicate with each other.
                                The QTCPServer is creating the socket and you get pointer to it via the nextPendingConnection call, so you're actually not (explicitly) creating a QTcpSocket instance on your own.

                                In the next connect(), we call the displayError in case of any connection error. Connection errors may happen due to the Internet, operating system or the hardware failures. Using QAbstractSocket::errorOccurred we try to catch and then show them to the user. Right?

                                well, off all those
                                https://doc.qt.io/qt-5/qabstractsocket.html#SocketError-enum
                                and yes unplugging the hardware cable etc should generate an error you can catch here
                                8926b6e4-ef56-480a-a2b3-be48ab7a4bec-image.png

                                Using the second connect() in the slot above, we aim to delete the clientConnection when we later on exit the slot! But this is ambiguous! If the clientConnection was the one we already sent from the client app, why should we delete it when we exit the slot (onNewConnection)? So something in my assumptions should not be correct!

                                sockets aren't sent anywhere, they are parented to the QTcpServer instance, but when you don't need them anymore, you should delete them to free memory, thats what the delete later is for.
                                https://doc.qt.io/qt-5/qtcpserver.html#nextPendingConnection

                                The socket is created as a child of the server, which means that it is automatically deleted when the QTcpServer object is destroyed. It is still a good idea to delete the object explicitly when you are done with it, to avoid wasting memory.


                                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                Q: What's that?
                                A: It's blue light.
                                Q: What does it do?
                                A: It turns blue.

                                1 Reply Last reply
                                2
                                • Q Offline
                                  Q Offline
                                  qcoderpro
                                  wrote on last edited by
                                  #16

                                  @J-Hilk @jsulm
                                  OK, thank you both. To clarify the dark things more, I run both projects and type the IP address, port number (provided by the server) and a "Hi" message on the client app and click on the Send button on it. The message will be printed on the server's UI.

                                  tretet.PNG

                                  Let's explore what happens one by one.

                                  1. A socket is an endpoint instance in a communication through a computer network and is defined by an IP address and a port number. So the first socket is (192.168.56.1 and 53386) and either of the apps is an endpoint. We send that socket (I mean that IP and port) to the server app which will be caught by the connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection); and this, in turn, invokes the onNewConnection slot. There, a new socket (the server's side one) will be created to form the connection with the first socket from the client, completely. Therefore, communications through networks are made via sockets and through them data will be exchanged too. Agree with these all, please?

                                  2. For the clientConnection socket, the displayError will aim at catching errors (if any) and that socket is then set for deletion when we exit the onNewConnection slot.

                                  3. Then we assign clientConnection to be the device the DataStream in will use for data exchange as the output and the first socket will act like input for that data.

                                  Agree with 2 & 3 too?

                                  J.HilkJ 1 Reply Last reply
                                  0
                                  • Q qcoderpro

                                    @J-Hilk @jsulm
                                    OK, thank you both. To clarify the dark things more, I run both projects and type the IP address, port number (provided by the server) and a "Hi" message on the client app and click on the Send button on it. The message will be printed on the server's UI.

                                    tretet.PNG

                                    Let's explore what happens one by one.

                                    1. A socket is an endpoint instance in a communication through a computer network and is defined by an IP address and a port number. So the first socket is (192.168.56.1 and 53386) and either of the apps is an endpoint. We send that socket (I mean that IP and port) to the server app which will be caught by the connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection); and this, in turn, invokes the onNewConnection slot. There, a new socket (the server's side one) will be created to form the connection with the first socket from the client, completely. Therefore, communications through networks are made via sockets and through them data will be exchanged too. Agree with these all, please?

                                    2. For the clientConnection socket, the displayError will aim at catching errors (if any) and that socket is then set for deletion when we exit the onNewConnection slot.

                                    3. Then we assign clientConnection to be the device the DataStream in will use for data exchange as the output and the first socket will act like input for that data.

                                    Agree with 2 & 3 too?

                                    J.HilkJ Offline
                                    J.HilkJ Offline
                                    J.Hilk
                                    Moderators
                                    wrote on last edited by
                                    #17

                                    @qcoderpro said in Staring Qt network programming:

                                    Agree with these all, please

                                    no, but close enough

                                    For the clientConnection socket, the displayError will aim at catching errors (if any)

                                    yes

                                    and that socket is then set for deletion when we exit the onNewConnection slot.

                                    no, its set for deletion when the socket connection is lost, not for the scope end of onNewConnection, as the QTcpSocket is heap allocated.

                                    Then we assign clientConnection to be the device the DataStream in will use for data exchange as the output and the first socket will act like input for that data.

                                    yes


                                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                    Q: What's that?
                                    A: It's blue light.
                                    Q: What does it do?
                                    A: It turns blue.

                                    Q 1 Reply Last reply
                                    1
                                    • J.HilkJ J.Hilk

                                      @qcoderpro said in Staring Qt network programming:

                                      Agree with these all, please

                                      no, but close enough

                                      For the clientConnection socket, the displayError will aim at catching errors (if any)

                                      yes

                                      and that socket is then set for deletion when we exit the onNewConnection slot.

                                      no, its set for deletion when the socket connection is lost, not for the scope end of onNewConnection, as the QTcpSocket is heap allocated.

                                      Then we assign clientConnection to be the device the DataStream in will use for data exchange as the output and the first socket will act like input for that data.

                                      yes

                                      Q Offline
                                      Q Offline
                                      qcoderpro
                                      wrote on last edited by
                                      #18

                                      @J-Hilk

                                      no, but close enough

                                      1. Is the statement "We send that socket (I mean ..." what you disagree with, please, or other things in 1) too?

                                      its set for deletion when the socket connection is lost

                                      1. When is that connection lost, please? Is it when we close both projects (or one of them)? I say that because when we once send the IP and port number to the server and the connection is that way established, we can send as many messages as we wish to, without sending the IP and port number another time.

                                      2. For the line in.setVersion(QDataStream::Qt_4_0); we can use QDataStream::Qt_6_3 rather than that version 4 but the important matter is that the other app ought to use the same version too. Right?

                                      3. And the connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::writeMessage); will invoke the the slot writeMessage when the QDataStream in notifies its device's socket (clientConnection) that a message has completely arrived from the sender and is now ready to read. Right?

                                      Q 1 Reply Last reply
                                      0
                                      • Q qcoderpro

                                        @J-Hilk

                                        no, but close enough

                                        1. Is the statement "We send that socket (I mean ..." what you disagree with, please, or other things in 1) too?

                                        its set for deletion when the socket connection is lost

                                        1. When is that connection lost, please? Is it when we close both projects (or one of them)? I say that because when we once send the IP and port number to the server and the connection is that way established, we can send as many messages as we wish to, without sending the IP and port number another time.

                                        2. For the line in.setVersion(QDataStream::Qt_4_0); we can use QDataStream::Qt_6_3 rather than that version 4 but the important matter is that the other app ought to use the same version too. Right?

                                        3. And the connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::writeMessage); will invoke the the slot writeMessage when the QDataStream in notifies its device's socket (clientConnection) that a message has completely arrived from the sender and is now ready to read. Right?

                                        Q Offline
                                        Q Offline
                                        qcoderpro
                                        wrote on last edited by
                                        #19

                                        No more help!? :(

                                        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