Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. IS QTSocket a bogus?
Qt 6.12 LTS is out! See what's new in the release blog

IS QTSocket a bogus?

Scheduled Pinned Locked Moved Unsolved General and Desktop
14 Posts 4 Posters 2.6k 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.
  • Christian EhrlicherC Christian Ehrlicher

    @mariappan said in IS QTSocket a bogus?:

    1.Why ReadyReady is not unblocked twice .
    2.same ip and port when new connection is called for the first packet .and ready read also called .i try not to process the message as it may cause the slot not called for second packet .

    Because that is how a stream is working - there are no 'packets' on the wire, just bytes in a stream without any additional information. This will also be the same if you use pure WinAPI or anything else.

    mariappanM Offline
    mariappanM Offline
    mariappan
    wrote on last edited by
    #3

    @Christian-Ehrlicher thanks for the quick reply .
    As i understand normal window socket

    1. accept is blocking call when a new connection comes it gets unblocked.
    2. recev is also a blocking call when ever the client sends data it gets unblocked and since recev is while(1) loop in server ,server once again waits on blocked Recev call for the another packet .

    Coming to QTSocket

    connect for new connection is unblocked . when client connects to the server for the first time and goes to execute the connect of ReadyRead.

    now client send the data .
    ReadyReady needs to be unblocked .
    after few second
    now client send another data
    ReadyReady should be unblocked second time .

    I am stuck up here .please help

    Christian EhrlicherC 1 Reply Last reply
    0
    • mariappanM mariappan

      @Christian-Ehrlicher thanks for the quick reply .
      As i understand normal window socket

      1. accept is blocking call when a new connection comes it gets unblocked.
      2. recev is also a blocking call when ever the client sends data it gets unblocked and since recev is while(1) loop in server ,server once again waits on blocked Recev call for the another packet .

      Coming to QTSocket

      connect for new connection is unblocked . when client connects to the server for the first time and goes to execute the connect of ReadyRead.

      now client send the data .
      ReadyReady needs to be unblocked .
      after few second
      now client send another data
      ReadyReady should be unblocked second time .

      I am stuck up here .please help

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #4

      @mariappan said in IS QTSocket a bogus?:

      ReadyReady needs to be unblocked .

      What does this mean? readyRead() signal is emitted as soon as there is data available (except you are blocking the event loop to prevent the signal emission).

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      mariappanM 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        @mariappan said in IS QTSocket a bogus?:

        ReadyReady needs to be unblocked .

        What does this mean? readyRead() signal is emitted as soon as there is data available (except you are blocking the event loop to prevent the signal emission).

        mariappanM Offline
        mariappanM Offline
        mariappan
        wrote on last edited by
        #5

        @Christian-Ehrlicher hi Christian.
        Basically this my intension
        struct Data1{
        int a,
        int b,
        int d,
        };
        struct Data2{
        int x;
        int y ;
        int z;
        };

        Serilized data1(12bytes suppose) using memcpy used sent through QTCP Client socket .
        after some second delay
        Serilized data2((12bytes suppose) using memcpy and sent through QTCP client socket .

        Server side .
        pseduo code
        connect(QTCPServer ....... slot(newconnection()));

        my newconnection function is called .

        void newconnection()
        {
        connect(QTCPSocket,signal(ReadyRead(),,,,,slot(ReadData());
        }

        void ReadData()
        {
        cout<<"Read data claalled"
        QByteStream data = QTCPSocket->ReadAll();
        cout<<data.size() // it prints 12 . if altleast printed 24 i would rather agree it is bytestream it send at one shot and i need to work on segregating the message manually. but the size is only 12 bytes .

        with wireshark data is sent and received confirmation is done.

        tried to invoke event loop but still i didnt get the second packet.

        please help...

        Christian EhrlicherC JonBJ 2 Replies Last reply
        0
        • mariappanM mariappan

          @Christian-Ehrlicher hi Christian.
          Basically this my intension
          struct Data1{
          int a,
          int b,
          int d,
          };
          struct Data2{
          int x;
          int y ;
          int z;
          };

          Serilized data1(12bytes suppose) using memcpy used sent through QTCP Client socket .
          after some second delay
          Serilized data2((12bytes suppose) using memcpy and sent through QTCP client socket .

          Server side .
          pseduo code
          connect(QTCPServer ....... slot(newconnection()));

          my newconnection function is called .

          void newconnection()
          {
          connect(QTCPSocket,signal(ReadyRead(),,,,,slot(ReadData());
          }

          void ReadData()
          {
          cout<<"Read data claalled"
          QByteStream data = QTCPSocket->ReadAll();
          cout<<data.size() // it prints 12 . if altleast printed 24 i would rather agree it is bytestream it send at one shot and i need to work on segregating the message manually. but the size is only 12 bytes .

          with wireshark data is sent and received confirmation is done.

          tried to invoke event loop but still i didnt get the second packet.

          please help...

          Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by Christian Ehrlicher
          #6

          It does work for all others so you are doing something wrong. So either work through the examples of QTcpSocket (Fortune server/client, leave alone the threading examples, they are not neeeded in your case) or provide a minimal, compilable example to reproduce your issue (and please format you code with the code - tags (</> button) so it is readable.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          1 Reply Last reply
          3
          • mariappanM mariappan

            @Christian-Ehrlicher hi Christian.
            Basically this my intension
            struct Data1{
            int a,
            int b,
            int d,
            };
            struct Data2{
            int x;
            int y ;
            int z;
            };

            Serilized data1(12bytes suppose) using memcpy used sent through QTCP Client socket .
            after some second delay
            Serilized data2((12bytes suppose) using memcpy and sent through QTCP client socket .

            Server side .
            pseduo code
            connect(QTCPServer ....... slot(newconnection()));

            my newconnection function is called .

            void newconnection()
            {
            connect(QTCPSocket,signal(ReadyRead(),,,,,slot(ReadData());
            }

            void ReadData()
            {
            cout<<"Read data claalled"
            QByteStream data = QTCPSocket->ReadAll();
            cout<<data.size() // it prints 12 . if altleast printed 24 i would rather agree it is bytestream it send at one shot and i need to work on segregating the message manually. but the size is only 12 bytes .

            with wireshark data is sent and received confirmation is done.

            tried to invoke event loop but still i didnt get the second packet.

            please help...

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by
            #7

            @mariappan
            The Qt socket stuff works fine and as documented. If the first readyRead() only gets 12 bytes, for whatever reason, the signal will be emitted again for the further 12 bytes. Make sure (a) you have the event loop running and (b) you exit your slot when you are done with the first 12 bytes. https://doc.qt.io/qt-6/qiodevice.html#readyRead

            This signal is emitted once every time new data is available for reading from the device's current read channel. It will only be emitted again once new data is available, such as when a new payload of network data has arrived on your network socket, or when a new block of data has been appended to your device.

            readyRead() is not emitted recursively; if you reenter the event loop or call waitForReadyRead() inside a slot connected to the readyRead() signal, the signal will not be reemitted

            If you want to verify remove all your code and just try a standalone minimal program.

            mariappanM 1 Reply Last reply
            1
            • JonBJ JonB

              @mariappan
              The Qt socket stuff works fine and as documented. If the first readyRead() only gets 12 bytes, for whatever reason, the signal will be emitted again for the further 12 bytes. Make sure (a) you have the event loop running and (b) you exit your slot when you are done with the first 12 bytes. https://doc.qt.io/qt-6/qiodevice.html#readyRead

              This signal is emitted once every time new data is available for reading from the device's current read channel. It will only be emitted again once new data is available, such as when a new payload of network data has arrived on your network socket, or when a new block of data has been appended to your device.

              readyRead() is not emitted recursively; if you reenter the event loop or call waitForReadyRead() inside a slot connected to the readyRead() signal, the signal will not be reemitted

              If you want to verify remove all your code and just try a standalone minimal program.

              mariappanM Offline
              mariappanM Offline
              mariappan
              wrote on last edited by
              #8

              @JonB thanks JonB .
              Things goes back to 2014 .
              https://forum.qt.io/topic/48868/solved-qtcpsocket-readyread-only-signaled-once/4?_=1712905617681

              But normally TCP_RESET will be called for all messages . i dont know how he solved .

              And also i made sure i dont sit in slot function i just print the size and come out immeditately

              JonBJ 1 Reply Last reply
              0
              • mariappanM mariappan

                @JonB thanks JonB .
                Things goes back to 2014 .
                https://forum.qt.io/topic/48868/solved-qtcpsocket-readyread-only-signaled-once/4?_=1712905617681

                But normally TCP_RESET will be called for all messages . i dont know how he solved .

                And also i made sure i dont sit in slot function i just print the size and come out immeditately

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by
                #9

                @mariappan
                But the link you quote ended with the OP saying:

                Fixed, turned out to be an issue with the server. The server was not replying to messages until a TCP reset occurred, then it would start replying to messages again, but at that time readyRead would not fire. Fixing the server seemed to have fixed to readyRead issue.

                So it was apparently not even a Qt bug then.

                Honestly, if you wan t to report a problem here you will need to show a minimal piece of code illustrating it. Remember that loads of people are using QTcpSocket....

                mariappanM 1 Reply Last reply
                0
                • JonBJ JonB

                  @mariappan
                  But the link you quote ended with the OP saying:

                  Fixed, turned out to be an issue with the server. The server was not replying to messages until a TCP reset occurred, then it would start replying to messages again, but at that time readyRead would not fire. Fixing the server seemed to have fixed to readyRead issue.

                  So it was apparently not even a Qt bug then.

                  Honestly, if you wan t to report a problem here you will need to show a minimal piece of code illustrating it. Remember that loads of people are using QTcpSocket....

                  mariappanM Offline
                  mariappanM Offline
                  mariappan
                  wrote on last edited by
                  #10

                  @JonB Thanks JonB

                  I made sure .

                  1. i didnt start a thread for the eventloop to exists
                  2. i didnt use waitforreadyReady() inside a loop .

                  wanted only two prints "Called ReadData" slots for two messages .

                  1. create QObjectclass and created tcpclient , tcpserver, tcpsocket .
                    2.sent the serlized data one after another .

                  There is no event loop as i am not in threads .

                  This made go back to winsocket . i dont know anything i am missing

                  Christian EhrlicherC JonBJ mariappanM 3 Replies Last reply
                  0
                  • mariappanM mariappan

                    @JonB Thanks JonB

                    I made sure .

                    1. i didnt start a thread for the eventloop to exists
                    2. i didnt use waitforreadyReady() inside a loop .

                    wanted only two prints "Called ReadData" slots for two messages .

                    1. create QObjectclass and created tcpclient , tcpserver, tcpsocket .
                      2.sent the serlized data one after another .

                    There is no event loop as i am not in threads .

                    This made go back to winsocket . i dont know anything i am missing

                    Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by Christian Ehrlicher
                    #11

                    @mariappan said in IS QTSocket a bogus?:

                    This made go back to winsocket . i dont know anything i am missing

                    Do whatever you want - as we already told you it works but you doing something wrong and there are even full working examples in the link I gave you but you ignore them.
                    Stripping down an app to reproduce the issue to a minimal, compilable example is the basic work of an developer.

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    1 Reply Last reply
                    1
                    • mariappanM mariappan

                      @JonB Thanks JonB

                      I made sure .

                      1. i didnt start a thread for the eventloop to exists
                      2. i didnt use waitforreadyReady() inside a loop .

                      wanted only two prints "Called ReadData" slots for two messages .

                      1. create QObjectclass and created tcpclient , tcpserver, tcpsocket .
                        2.sent the serlized data one after another .

                      There is no event loop as i am not in threads .

                      This made go back to winsocket . i dont know anything i am missing

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #12

                      @mariappan said in IS QTSocket a bogus?:

                      i dont know anything i am missing

                      When you want to report a bug or problem in a piece of software you need to supply a minimal reproducible example. This is standard across all software. Then either people might show what you have done "wrong" or agree there is indeed a problem, in which case it will be investigated.

                      1 Reply Last reply
                      0
                      • mariappanM mariappan

                        @JonB Thanks JonB

                        I made sure .

                        1. i didnt start a thread for the eventloop to exists
                        2. i didnt use waitforreadyReady() inside a loop .

                        wanted only two prints "Called ReadData" slots for two messages .

                        1. create QObjectclass and created tcpclient , tcpserver, tcpsocket .
                          2.sent the serlized data one after another .

                        There is no event loop as i am not in threads .

                        This made go back to winsocket . i dont know anything i am missing

                        mariappanM Offline
                        mariappanM Offline
                        mariappan
                        wrote on last edited by
                        #13

                        @mariappan i just check once again and come back

                        C 1 Reply Last reply
                        1
                        • mariappanM mariappan

                          @mariappan i just check once again and come back

                          C Offline
                          C Offline
                          ChrisW67
                          wrote on last edited by
                          #14

                          @mariappan Perhaps if you run this client/server pair you will better understand what is happening, and why this is not "a bogus".

                          Client:

                          #ifndef CLIENT_H
                          #define CLIENT_H
                          
                          #include <QObject>
                          #include <QTcpSocket>
                          #include <QTimer>
                          
                          class Client : public QObject
                          {
                              Q_OBJECT
                          public:
                              explicit Client(QObject *parent = nullptr);
                          
                          private slots:
                              void handleConnected();
                              void handleDisconnected();
                              void handleErrorOccurred(QAbstractSocket::SocketError socketError);
                              void handleBytesWritten(qint64 bytes);
                              void sendPacket();
                          
                          private:
                              QTcpSocket *m_socket;
                              QTimer *m_timer;
                              int m_packetNo;
                          };
                          
                          #endif // CLIENT_H
                          
                          #include "client.h"
                          #include <QTimer>
                          #include <QRandomGenerator>
                          
                          Client::Client(QObject *parent)
                              : QObject{parent}
                              , m_socket{ new QTcpSocket(this) }
                              , m_timer{ new QTimer(this) }
                              , m_packetNo{0}
                          {
                              m_timer->setInterval(500);
                              connect(m_timer, &QTimer::timeout, this, &Client::sendPacket);
                              connect(m_socket, &QTcpSocket::connected, this, &Client::handleConnected);
                              connect(m_socket, &QTcpSocket::disconnected, this, &Client::handleDisconnected);
                              connect(m_socket, &QTcpSocket::errorOccurred, this, &Client::handleErrorOccurred);
                              connect(m_socket, &QIODevice::bytesWritten, this, &Client::handleBytesWritten);
                          
                              m_socket->connectToHost(QHostAddress("127.0.0.1"), 12345);
                          }
                          
                          void Client::handleConnected() {
                              qDebug() << "Connected, sending packets.";
                              m_timer->start();
                          
                          }
                          
                          void Client::handleDisconnected() {
                              qDebug() << "Disconnected";
                              m_timer->stop();
                          }
                          
                          void Client::handleErrorOccurred(QAbstractSocket::SocketError socketError) {
                              qDebug() << "Error occured" << socketError;
                              m_timer->stop();
                          }
                          
                          void Client::handleBytesWritten(qint64 bytes) {
                              qDebug() << "Bytes written" << bytes;
                          }
                          
                          void Client::sendPacket() {
                              // Generate a sample fixed-length payload
                              QByteArray data;
                              data.setNum(m_packetNo++);
                              data = data.rightJustified(32, '.');
                              m_socket->write(data);
                              qDebug() << "Wrote" << data;
                          
                              // Sometimes we write more than one
                              quint32 value = QRandomGenerator::global()->generate();
                              if ((value % 3) == 1) {
                                  data.setNum(m_packetNo++);
                                  data = data.rightJustified(32, '*');
                                  m_socket->write(data);
                                  qDebug() << "Wrote" << data;
                              }
                          }
                          
                          #include <QCoreApplication>
                          #include <QDebug>
                          #include <QTimer>
                          
                          #include "client.h"
                          
                          int main(int argc, char **argv) {
                              QCoreApplication app(argc, argv);
                              Client client;
                              QTimer::singleShot(30000, qApp, &QCoreApplication::quit);
                          	return app.exec();
                          }
                          

                          Server:

                          #ifndef SERVER_H
                          #define SERVER_H
                          
                          #include <QObject>
                          #include <QTcpServer>
                          
                          
                          
                          class Server : public QObject
                          {
                              Q_OBJECT
                          public:
                              explicit Server(QObject *parent = nullptr);
                          
                          private slots:
                              void handleNewConnection();
                          
                          private:
                              QTcpServer *m_server;
                          };
                          
                          
                          class ClientHandler: public QObject {
                              Q_OBJECT
                          public:
                              explicit ClientHandler(QTcpSocket *socket, QObject *p = nullptr);
                          private slots:
                              void handleReadyRead();
                              void handleDisconnected();
                          private:
                              QTcpSocket *m_socket;
                          };
                          
                          
                          #endif // SERVER_H
                          
                          #include "server.h"
                          
                          #include <QDebug>
                          #include <QTcpSocket>
                          
                          Server::Server(QObject *parent)
                              : QObject{parent}
                              , m_server{ new QTcpServer(this) }
                          {
                              connect(m_server, &QTcpServer::newConnection, this, &Server::handleNewConnection);
                              m_server->listen(QHostAddress("127.0.0.1"), 12345);
                          }
                          
                          void Server::handleNewConnection() {
                              while(m_server->hasPendingConnections()) {
                                  QTcpSocket *socket = m_server->nextPendingConnection();
                                  qDebug() << "Accepted connection from " << socket->peerAddress() << socket;
                                  ClientHandler *client = new ClientHandler(socket, this);
                                  Q_UNUSED(client);
                              }
                          }
                          
                          ClientHandler::ClientHandler(QTcpSocket *socket, QObject *p)
                              : QObject(p)
                              , m_socket(socket)
                          {
                              socket->setParent(this);
                              connect(socket, &QTcpSocket::readyRead, this, &ClientHandler::handleReadyRead);
                              connect(socket, &QTcpSocket::disconnected, this, &ClientHandler::handleDisconnected);
                          }
                          
                          void ClientHandler::handleReadyRead() {
                              qDebug() << m_socket<< "readyRead received.";
                              QByteArray data = m_socket->readAll();
                              qDebug() << data;
                          }
                          
                          void ClientHandler::handleDisconnected() {
                              qDebug() << m_socket << "disconnect";
                              deleteLater();
                          }
                          
                          #include <QCoreApplication>
                          
                          #include "server.h"
                          
                          int main(int argc, char **argv) {
                          	QCoreApplication app(argc, argv);
                          
                              Server server;
                          
                          	return app.exec();
                          }
                          
                          1 Reply Last reply
                          1
                          • C ChrisW67 referenced this topic on

                          • Login

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