Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. IS QTSocket a bogus?
Forum Updated to NodeBB v4.3 + New Features

IS QTSocket a bogus?

Scheduled Pinned Locked Moved Unsolved General and Desktop
14 Posts 4 Posters 967 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.
  • mariappanM Offline
    mariappanM Offline
    mariappan
    wrote on last edited by
    #1

    Hi ,

    I send two packets to QTSocket .My ReadyRead is unblocked only once .very pathethic this made to leave the QTSocketing and go for windows sockets .please help.
    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 . just print alone readReady() functgion called .
    I get only one debug print for the first message and for the second message my readyReady never unblocked .

    Christian EhrlicherC 1 Reply Last reply
    0
    • mariappanM mariappan

      Hi ,

      I send two packets to QTSocket .My ReadyRead is unblocked only once .very pathethic this made to leave the QTSocketing and go for windows sockets .please help.
      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 . just print alone readReady() functgion called .
      I get only one debug print for the first message and for the second message my readyReady never unblocked .

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

      @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.

      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?:

        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 Extensions
                              • Unsolved