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. Sending messages from a client to server using network on the same machine
QtWS25 Last Chance

Sending messages from a client to server using network on the same machine

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
31 Posts 4 Posters 5.4k 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 21 Mar 2022, 20:10 last edited by
    #1

    Hi all,

    This is my first attempt to get my feet wet with network programming. After reading some references I decided to learn the stuff in action by creating the following two QtQuick projects called server and client using Qt 6.2 on my Windows machine.
    The purpose is to be able to connect to a server (using an IP and port) and then send messages to it. I guess it's a simple task for networking but since I'm completely new to this area there may be silly mistakes in the code of the two projects.

    First client.qml
    Client.h:

    #include <QDataStream>
    #include <QTcpSocket>
    
    class QTcpSocket;
    
    class Client : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QVector<QString> addresses READ readAddress CONSTANT);
    
    public:
        explicit Client(QObject *parent = nullptr);
        QVector<QString> readAddress() const;
    
    public slots:
        void sendMessage(QString, QString); // Called from the front-end
        QString readMessage(); // Called from the front-end
    
    private:
        QTcpSocket* tcpSocket { nullptr };
        QDataStream in;
        QVector<QString> addresses;
    };
    

    Client.cpp:

    #include "client.h"
    #include <QtNetwork>
    #include <QtCore>
    
    Client::Client(QObject *parent)
        : QObject{parent}
        , tcpSocket(new QTcpSocket(this))
    {
        /* find out name and IP addresses of this machine
            non-localhost addresses add localhost addresses
            and add all to the vector (addresses)
       */ 
      // Addresses all are shown properly on the front-end part
    
        in.setDevice(tcpSocket);
        in.setVersion(QDataStream::Qt_4_0);
        connect(tcpSocket, &QIODevice::readyRead, this, &Client::readMessage);
    }
    
    void Client::sendMessage(QString ip, QString port)
    {
        tcpSocket->abort();
        tcpSocket->connectToHost(ip, port.toInt());
    }
    
    QVector<QString> Client::readAddress() const
    {
        return addresses;
    }
    
    QString Client::readMessage() {
        in.startTransaction();
    
        QString message;
        in >> message;
    
        if (!in.commitTransaction())
            return "Error";
        return message;
    }
    

    And this is server.qml
    Server.h:

    #include <QObject>
    
    class QTcpServer;
    class QTcpSocket;
    
    class Server : public QObject
    {
        Q_OBJECT
    
    public:
        explicit Server(QObject *parent = nullptr);
    
    public slots:
        QString initServer();
        QString setMessage();
    
    private:
        QTcpServer* tcpServer { nullptr };
        QTcpSocket* tcpSocket { nullptr };
        QDataStream in;
    };
    

    Server.cpp:

    #include "server.h"
    #include <QtNetwork>
    #include <QtCore>
    
    Server::Server(QObject *parent)
        : QObject{parent}
        , tcpServer(new QTcpServer(this))
        , tcpSocket(new QTcpSocket(this))
    {
        initServer();
    }
    
    QString Server::initServer() {
    
        tcpServer = new QTcpServer(this);
        if(!tcpServer->listen())
            return "Server Unable to start the server: " +
                    tcpServer->errorString();
    
        QString ipAddress;
        QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
    
       /* use the first non-local IPv4 address if we did not find one, use IPv4 
            localhost, then return IP and port number. 
       */
        in.setDevice(tcpSocket);
        in.setVersion(QDataStream::Qt_4_0);
    }
    
    QString Server::setMessage()
    {
        in.startTransaction();
    
        QString message;
        in >> message;
    
        if (!in.commitTransaction())
            return "commitTransaction error" ;
    
        return message;
    }
    

    When both projects run at the same time, firstly this message appears in Application Output: QDataStream: No transaction in progress

    Then after selecting the IP and port number on the Client (based on what Server has provided) and clicking on the Send button to send a simple Hello message, errors bellow will come up on the apps':
    dsds.PNG

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 21 Mar 2022, 20:37 last edited by
      #2

      Hi,

      You are not handling new connections in your server part.

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

      Q 1 Reply Last reply 22 Mar 2022, 19:26
      1
      • S SGaist
        21 Mar 2022, 20:37

        Hi,

        You are not handling new connections in your server part.

        Q Offline
        Q Offline
        qcoderpro
        wrote on 22 Mar 2022, 19:26 last edited by
        #3

        @SGaist

        I explored server.cpp well but am not sure how to do that. :|

        1 Reply Last reply
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 22 Mar 2022, 19:27 last edited by
          #4

          Did you check the fortune client and server examples ?

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

          Q 1 Reply Last reply 22 Mar 2022, 19:58
          1
          • S SGaist
            22 Mar 2022, 19:27

            Did you check the fortune client and server examples ?

            Q Offline
            Q Offline
            qcoderpro
            wrote on 22 Mar 2022, 19:58 last edited by
            #5

            @SGaist
            Yes. There a button on the client causes a message to be sent from the server to it which is different from mine. On my projects, the client itself sends messages to the sever.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 22 Mar 2022, 20:01 last edited by
              #6

              You are not handling new connection. See newConnection.

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

              Q 1 Reply Last reply 22 Mar 2022, 20:18
              0
              • S SGaist
                22 Mar 2022, 20:01

                You are not handling new connection. See newConnection.

                Q Offline
                Q Offline
                qcoderpro
                wrote on 22 Mar 2022, 20:18 last edited by
                #7

                @SGaist

                I want to define: connect(tcpServer, &QTcpServer::newConnection, this, &Server:: ...); but don't know what slot to be called for that. Please remember my server app is the receiver of the messages and there's only a lost, setMessage(), defined in it apart from initServer().

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 22 Mar 2022, 20:33 last edited by
                  #8

                  It means that you need to store the socket that is created to handle the connection with your client.
                  Then connect that socket readyRead signal to the slot that will process the message.

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

                  Q 1 Reply Last reply 23 Mar 2022, 19:05
                  1
                  • S SGaist
                    22 Mar 2022, 20:33

                    It means that you need to store the socket that is created to handle the connection with your client.
                    Then connect that socket readyRead signal to the slot that will process the message.

                    Q Offline
                    Q Offline
                    qcoderpro
                    wrote on 23 Mar 2022, 19:05 last edited by
                    #9

                    @SGaist
                    I'm really confused. Let's get it straight, please.
                    Just to emphasize: The goal of the two projects is that: First the Server app provides IP and port number. Then the Client app uses those IP and port to connect to the Server, then using a textfiled and a send button it (the client) sends messages to the server.

                    Now I've got two questions:

                    1. Are the projects Server and Client defined in the first post of this thread right for that goal?
                    2. If so, I assume I need to add connect(tcpServer, &QTcpServer::newConnection, this, &Server::setMessage); to the Server app and connect(tcpSocket, &QIODevice::readyRead, this, &Client::sendMessage); to the Client app. Right up to here?
                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on 23 Mar 2022, 21:05 last edited by
                      #10

                      Client and server separation are correct however, what you are missing is the handling of the socket server side. When a new connection is attempted, it will create a socket on the server to allow communication with the client, and that's why you need to store that socket to be able to do communication with it.

                      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
                      2
                      • Q Offline
                        Q Offline
                        qcoderpro
                        wrote on 24 Mar 2022, 18:19 last edited by
                        #11

                        You mentioned "storing a socket" a couple of times, but I don't know what you mean by storing a socket!

                        What I know from rereading your previous messages up to here is that I need to set the connection below in the server side to store the coming socket (how?):
                        connect(tcpServer, &QTcpServer::newConnection, this, &Server:: ...);
                        Then it's required to use that stored socket in: connect(tcpSocket, &QIODevice::readyRead, this, &Client::setMessage); (the setMessage slot will set the message to the label)

                        Is it not possible to write a few lines of code for the projects to get them to work, please? I'm sure I will definitely learn the whole stuff used for the both projects by reading your messages all (again) and looking at the codes.

                        1 Reply Last reply
                        0
                        • S Offline
                          S Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on 24 Mar 2022, 20:07 last edited by
                          #12

                          This is enough to receive data from your client and automatically delete the socket on disconnection however it will require to use the sender method to retrieve the data:

                          void Server::onNewConnection()
                          {
                              QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
                              connect(clientConnection, &QAbstractSocket::disconnected,
                                      clientConnection, &QObject::deleteLater);
                              connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::processMessage);
                          }
                          

                          The other solution would be to use a lambda rather than a slot.
                          Lastly, depending on what else you want to do with the socket object, you should add a member variable to your Server class to store it, whether it's a QTcpSocket pointer or a vector of them will depend on how much connections you are going to allow to your server.

                          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
                          1
                          • Q Offline
                            Q Offline
                            qcoderpro
                            wrote on 25 Mar 2022, 21:28 last edited by qcoderpro
                            #13

                            The example is much harder than I thought of! :|
                            I had to simplify the examples as much as possible to get the topic and can get them to work as expected. I'm sorry that I send the examples part of which may be repetitive.
                            (The purpose is the same: connecting client to the server and then sending messages to it)
                            client.h

                            class QTcpSocket;
                            
                            class Client : public QObject
                            {
                                Q_OBJECT
                            
                            public:
                                explicit Client(QObject *parent = nullptr);
                            
                            public slots:
                                void sendMessage(QString, QString);
                            
                            private:
                                QTcpSocket* tcpSocket { nullptr };
                                QDataStream in;
                            };
                            

                            client.cpp

                            #include "client.h"
                            #include <QtNetwork>
                            
                            Client::Client(QObject *parent)
                                : QObject{parent}
                                , tcpSocket(new QTcpSocket(this))
                            {
                                in.setDevice(tcpSocket);
                                in.setVersion(QDataStream::Qt_4_0);
                            }
                            
                            void Client::sendMessage(QString ip, QString port)
                            {
                                tcpSocket->abort();
                                tcpSocket->connectToHost(ip, port.toInt());
                            }
                            

                            main.qml

                            Window {
                                width: 300
                                height: 200
                                visible: true
                                title: qsTr("Client")
                                color: "lightblue"
                            
                                ColumnLayout {
                                    anchors.fill: parent
                            
                                    TextField {
                                        id: ipAddrs
                                    }
                                    TextField {
                                            id: portNum
                                        }
                            
                                    RowLayout {
                                        Layout.alignment: Qt.AlignBottom
                            
                                        TextField {
                                            id: txtField
                                            Layout.fillWidth: true
                                        }
                                        Button {
                                            text: qsTr("Send")
                                            onClicked:
                                            myObject.sendMessage(ipAddrs.text.toString(), portNum.text.toString())
                                        }
                                    }
                                }
                            
                                MyObject{
                                    id: myObject
                                }
                            }
                            

                            server.h

                            class QTcpServer;
                            class QTcpSocket;
                            
                            class Server : public QObject
                            {
                                Q_OBJECT
                            public:
                                explicit Server(QObject *parent = nullptr);
                            
                            public slots:
                                QString initServer();
                                QString setMessage();
                                void onNewConnection();
                            
                            private:
                                QTcpServer* tcpServer { nullptr };
                                QTcpSocket* tcpSocket { nullptr };
                                QDataStream in;
                            };
                            

                            server.cpp

                            #include "server.h"
                            #include <QtNetwork>
                            #include <QtCore>
                            
                            Server::Server(QObject *parent)
                                : QObject{parent}
                                , tcpServer(new QTcpServer(this))
                                , tcpSocket(new QTcpSocket(this))
                            {
                                initServer();
                                in.setDevice(tcpSocket);
                                in.setVersion(QDataStream::Qt_4_0);
                                connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection);
                            }
                            
                            QString Server::initServer() {
                            
                                tcpServer = new QTcpServer(this);
                                if(!tcpServer->listen())
                                    return "Server Unable to start the server: " +
                                            tcpServer->errorString();
                            
                                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);
                                connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::setMessage);
                            }
                            
                            QString Server::setMessage()
                            {
                                in.startTransaction();
                            
                                QString message;
                                in >> message;
                            
                                if (!in.commitTransaction())
                                   return "commitTransaction error" ;
                            
                                return message;
                            }
                            

                            main.qml

                            Window {
                                width: 300
                                height: 200
                                visible: true
                                title: qsTr("Server")
                                color: "lightblue"
                            
                                ColumnLayout {
                                    anchors.fill: parent
                            
                                    Label {
                                        text: myObject.initServer()
                                    }
                            
                                    Label {
                                        id: msgLabel
                                        text: myObject.setMessage()
                                    }
                                }
                            
                                MyObject{
                                    id: myObject
                                }
                            }
                            

                            For now I have only a question. Are the projects to this point fine? I mean I know that there may be many things to be added to them but isn't anything redundant up to here?

                            Q 1 Reply Last reply 26 Mar 2022, 19:45
                            0
                            • Q qcoderpro
                              25 Mar 2022, 21:28

                              The example is much harder than I thought of! :|
                              I had to simplify the examples as much as possible to get the topic and can get them to work as expected. I'm sorry that I send the examples part of which may be repetitive.
                              (The purpose is the same: connecting client to the server and then sending messages to it)
                              client.h

                              class QTcpSocket;
                              
                              class Client : public QObject
                              {
                                  Q_OBJECT
                              
                              public:
                                  explicit Client(QObject *parent = nullptr);
                              
                              public slots:
                                  void sendMessage(QString, QString);
                              
                              private:
                                  QTcpSocket* tcpSocket { nullptr };
                                  QDataStream in;
                              };
                              

                              client.cpp

                              #include "client.h"
                              #include <QtNetwork>
                              
                              Client::Client(QObject *parent)
                                  : QObject{parent}
                                  , tcpSocket(new QTcpSocket(this))
                              {
                                  in.setDevice(tcpSocket);
                                  in.setVersion(QDataStream::Qt_4_0);
                              }
                              
                              void Client::sendMessage(QString ip, QString port)
                              {
                                  tcpSocket->abort();
                                  tcpSocket->connectToHost(ip, port.toInt());
                              }
                              

                              main.qml

                              Window {
                                  width: 300
                                  height: 200
                                  visible: true
                                  title: qsTr("Client")
                                  color: "lightblue"
                              
                                  ColumnLayout {
                                      anchors.fill: parent
                              
                                      TextField {
                                          id: ipAddrs
                                      }
                                      TextField {
                                              id: portNum
                                          }
                              
                                      RowLayout {
                                          Layout.alignment: Qt.AlignBottom
                              
                                          TextField {
                                              id: txtField
                                              Layout.fillWidth: true
                                          }
                                          Button {
                                              text: qsTr("Send")
                                              onClicked:
                                              myObject.sendMessage(ipAddrs.text.toString(), portNum.text.toString())
                                          }
                                      }
                                  }
                              
                                  MyObject{
                                      id: myObject
                                  }
                              }
                              

                              server.h

                              class QTcpServer;
                              class QTcpSocket;
                              
                              class Server : public QObject
                              {
                                  Q_OBJECT
                              public:
                                  explicit Server(QObject *parent = nullptr);
                              
                              public slots:
                                  QString initServer();
                                  QString setMessage();
                                  void onNewConnection();
                              
                              private:
                                  QTcpServer* tcpServer { nullptr };
                                  QTcpSocket* tcpSocket { nullptr };
                                  QDataStream in;
                              };
                              

                              server.cpp

                              #include "server.h"
                              #include <QtNetwork>
                              #include <QtCore>
                              
                              Server::Server(QObject *parent)
                                  : QObject{parent}
                                  , tcpServer(new QTcpServer(this))
                                  , tcpSocket(new QTcpSocket(this))
                              {
                                  initServer();
                                  in.setDevice(tcpSocket);
                                  in.setVersion(QDataStream::Qt_4_0);
                                  connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection);
                              }
                              
                              QString Server::initServer() {
                              
                                  tcpServer = new QTcpServer(this);
                                  if(!tcpServer->listen())
                                      return "Server Unable to start the server: " +
                                              tcpServer->errorString();
                              
                                  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);
                                  connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::setMessage);
                              }
                              
                              QString Server::setMessage()
                              {
                                  in.startTransaction();
                              
                                  QString message;
                                  in >> message;
                              
                                  if (!in.commitTransaction())
                                     return "commitTransaction error" ;
                              
                                  return message;
                              }
                              

                              main.qml

                              Window {
                                  width: 300
                                  height: 200
                                  visible: true
                                  title: qsTr("Server")
                                  color: "lightblue"
                              
                                  ColumnLayout {
                                      anchors.fill: parent
                              
                                      Label {
                                          text: myObject.initServer()
                                      }
                              
                                      Label {
                                          id: msgLabel
                                          text: myObject.setMessage()
                                      }
                                  }
                              
                                  MyObject{
                                      id: myObject
                                  }
                              }
                              

                              For now I have only a question. Are the projects to this point fine? I mean I know that there may be many things to be added to them but isn't anything redundant up to here?

                              Q Offline
                              Q Offline
                              qcoderpro
                              wrote on 26 Mar 2022, 19:45 last edited by
                              #14

                              When I run both projects, I get this issue for the client project:
                              QIODevice::read (QTcpSocket): device not open and the error message: commitTransaction error
                              on the server's project's user interface. Let's for now ignore these.

                              I type the IP and port numbers provided by the server UI into the text fields of the client project's UI and write "Hi" in the bottom text field and click on the button Send there for which the sendMessage slot is called and it connectes to the server successfully.

                              void Client::sendMessage(QString ip, QString port)
                              {
                                  tcpSocket->abort();
                                  tcpSocket->connectToHost(ip, port.toInt());
                              }
                              

                              Afterwards, we've this connection in the Server project's constructor:
                              connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection);
                              As well as:

                              in.setDevice(tcpSocket);
                              in.setVersion(QDataStream::Qt_4_0);
                              

                              The connection above calls onNewConnection slot since there's a new connection signal.

                              void Server::onNewConnection()
                              {
                                  QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
                                  connect(clientConnection, &QAbstractSocket::disconnected,
                                          clientConnection, &QObject::deleteLater);
                                  connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::setMessage);
                              }
                              

                              In that function the setMessage slot is called:

                              QString Server::setMessage()
                              {
                                  in.startTransaction();
                              
                                  QString message;
                                  in >> message;
                              
                                  if (!in.commitTransaction())
                                     return "commitTransaction error" ;
                              
                                  return message;
                              }
                              

                              in is already set to the socket in the constructor, so it's expected that it's able to get the message sent ('Hi') and return that message to the server's label front-end part where that slot is called (too)!
                              But in reality no message is shown on the server's UI!

                              Could you please tell me where the first mistake is in the code so that I can firstly fix it and then we go for the others?

                              1 Reply Last reply
                              0
                              • S Offline
                                S Offline
                                SGaist
                                Lifetime Qt Champion
                                wrote on 26 Mar 2022, 20:45 last edited by
                                #15

                                First thing: you initialize your QDataStream on the wrong socket, it shall use the socket matching the connection that was established.

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

                                Q 1 Reply Last reply 26 Mar 2022, 21:14
                                1
                                • S SGaist
                                  26 Mar 2022, 20:45

                                  First thing: you initialize your QDataStream on the wrong socket, it shall use the socket matching the connection that was established.

                                  Q Offline
                                  Q Offline
                                  qcoderpro
                                  wrote on 26 Mar 2022, 21:14 last edited by qcoderpro
                                  #16

                                  @SGaist

                                  Do you mean to move

                                  in.setDevice(tcpSocket);
                                  in.setVersion(QDataStream::Qt_4_0);
                                  

                                  from the server's constructor into the onNewConnection slot this way, please?

                                  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::setMessage);
                                  }
                                  

                                  The error message when running the projects both at the same time: QDataStream: No transaction in progress

                                  Q 1 Reply Last reply 28 Mar 2022, 12:52
                                  0
                                  • Q qcoderpro
                                    26 Mar 2022, 21:14

                                    @SGaist

                                    Do you mean to move

                                    in.setDevice(tcpSocket);
                                    in.setVersion(QDataStream::Qt_4_0);
                                    

                                    from the server's constructor into the onNewConnection slot this way, please?

                                    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::setMessage);
                                    }
                                    

                                    The error message when running the projects both at the same time: QDataStream: No transaction in progress

                                    Q Offline
                                    Q Offline
                                    qcoderpro
                                    wrote on 28 Mar 2022, 12:52 last edited by
                                    #17

                                    No further help? :|

                                    1 Reply Last reply
                                    0
                                    • S Offline
                                      S Offline
                                      SGaist
                                      Lifetime Qt Champion
                                      wrote on 28 Mar 2022, 18:11 last edited by
                                      #18

                                      Do you also use QDataStream to prepare the data to send ?

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

                                      Q 2 Replies Last reply 28 Mar 2022, 18:43
                                      0
                                      • S SGaist
                                        28 Mar 2022, 18:11

                                        Do you also use QDataStream to prepare the data to send ?

                                        Q Offline
                                        Q Offline
                                        qcoderpro
                                        wrote on 28 Mar 2022, 18:43 last edited by qcoderpro
                                        #19
                                        This post is deleted!
                                        1 Reply Last reply
                                        0
                                        • S SGaist
                                          28 Mar 2022, 18:11

                                          Do you also use QDataStream to prepare the data to send ?

                                          Q Offline
                                          Q Offline
                                          qcoderpro
                                          wrote on 28 Mar 2022, 19:27 last edited by
                                          #20

                                          @SGaist

                                          Yes, you're right. I partly changed all six files to match the requirements as follows:
                                          The server part:
                                          server.h:

                                          class Server : public QObject
                                          {
                                              Q_OBJECT
                                          public:
                                              explicit Server(QObject *parent = nullptr);
                                          
                                          public slots:
                                              QString initServer();
                                              void setMessage();
                                              QString getMessage() const;
                                              void onNewConnection();
                                          
                                          private:
                                              QTcpServer* tcpServer { nullptr };
                                              QDataStream in;
                                              QString message;
                                          };
                                          

                                          server.cpp:

                                          Server::Server(QObject *parent)
                                              : QObject{parent}
                                              , tcpServer(new QTcpServer(this))
                                          {
                                              initServer();
                                              connect(tcpServer, &QTcpServer::newConnection, this, &Server::onNewConnection);
                                          }
                                          
                                          QString Server::initServer() {
                                          //.. Provide the IP address and port number for the client
                                          }
                                          
                                          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::setMessage);
                                          }
                                          
                                          void Server::setMessage()
                                          {
                                              in.startTransaction();
                                              QString msg;
                                              in >> msg;
                                          
                                              if (!in.commitTransaction())
                                                  message = "commitTransaction error" ;
                                              else
                                                  message = msg;
                                          }
                                          
                                          QString Server::getMessage() const
                                          {
                                              return message;
                                          }
                                          

                                          server's qml file:

                                           ColumnLayout {
                                                  anchors.fill: parent
                                          
                                                  Label {
                                                      text: myObj.initServer()
                                                  }
                                          
                                                  Label {
                                                      id: msgLabel
                                                      text: myObj.getMessage()
                                                  }
                                              }
                                          
                                              ServerClass{
                                                  id: myObj
                                              }
                                          

                                          The client part:

                                          client.h:

                                          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:

                                          Client::Client(QObject *parent)
                                              : QObject{parent}
                                              , tcpSocket(new QTcpSocket(this))
                                          {
                                              out.setDevice(tcpSocket);
                                              out.setVersion(QDataStream::Qt_4_0);
                                          }
                                          
                                          void Client::sendAddress(QString ip, QString port)
                                          {
                                              tcpSocket->abort();
                                              tcpSocket->connectToHost(ip, port.toInt());
                                          }
                                          
                                          void Client::sendMessage(const QString& message)
                                          {
                                              out.startTransaction();
                                              out << message;
                                          
                                              if (!out.commitTransaction())
                                                  return ;
                                          }
                                          

                                          client's qml file:

                                           ColumnLayout {
                                                  anchors.fill: parent
                                          
                                                  TextField {
                                                      id: ipAddrs
                                                  }
                                                  TextField {
                                                          id: portNum
                                                      }
                                                  Button {
                                                      text: "Send Address"
                                                      onClicked: myObj.sendAddress(ipAddrs.text.toString(), portNum.text.toString())
                                                  }
                                          
                                                  RowLayout {
                                                      Layout.alignment: Qt.AlignBottom
                                          
                                                      TextField {
                                                          id: txtField
                                                          Layout.fillWidth: true
                                                      }
                                                      Button {
                                                          text: qsTr("Send")
                                                          onClicked: myObj.sendMessage(txtField.text)
                                                      }
                                                  }
                                              }
                                          
                                              ClientClass{
                                                  id: myObj
                                              }
                                          }
                                          

                                          After running both projects this way, and typing the IP address and port number (given by the server UI) on the client UI and writing a text message there I click on the Send button, but nothing is shown on the server UI.

                                          I'm almost sure now the goal is closer but there're still a number of mistakes that need to be worked out.

                                          1 Reply Last reply
                                          0

                                          7/31

                                          22 Mar 2022, 20:18

                                          topic:navigator.unread, 24
                                          • Login

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