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. problem with QLocalSocket sending continues data to QLocalServer
Forum Updated to NodeBB v4.3 + New Features

problem with QLocalSocket sending continues data to QLocalServer

Scheduled Pinned Locked Moved Solved General and Desktop
qlocalsocketqlocalserverreadyread
14 Posts 4 Posters 2.9k Views 1 Watching
  • 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.
  • V Venkateswaran

    @JonB yes I thought it's a one-to-one relationship. if I write 5 from client-side then I will get 5 readyRead signals.

    Christian EhrlicherC Online
    Christian EhrlicherC Online
    Christian Ehrlicher
    Lifetime Qt Champion
    wrote on last edited by Christian Ehrlicher
    #5

    @Venkateswaran Why? It's a stream with no further protocol. It can even happen that you get a readyRead signal for every single byte you sent.

    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
    • V Venkateswaran

      @JonB yes I thought it's a one-to-one relationship. if I write 5 from client-side then I will get 5 readyRead signals.

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

      @Venkateswaran
      And it absolutely is not! :)

      • readyRead fires when there is at least 1 byte available.
      • readAll reads all that happens to be there when it is called. Anything ranging from 0 bytes to every byte sent!
      • readyRead won't fire again till you've done a readAll.

      That's it. No one-to-one. Your job to buffer received data at receiver, or split it up, if that's what you want to do.

      V VRoninV 3 Replies Last reply
      0
      • JonBJ JonB

        @Venkateswaran
        And it absolutely is not! :)

        • readyRead fires when there is at least 1 byte available.
        • readAll reads all that happens to be there when it is called. Anything ranging from 0 bytes to every byte sent!
        • readyRead won't fire again till you've done a readAll.

        That's it. No one-to-one. Your job to buffer received data at receiver, or split it up, if that's what you want to do.

        V Offline
        V Offline
        Venkateswaran
        wrote on last edited by
        #7

        @JonB Thanks for clarifying this. Now I have another problem, on the server-side, I need to call another function with received test string from the client. I have tested the readAll() and as you said I'm receiving 130 bytes all at once (which is 5 times my test string). So how do I separate on server-side? I'm using QDataStream on client-side to send data and is there an elegant way to decouple the received bytes at server-side with QDataStream? maybe its a really basic question but it would be helpful for me if you show some example.

        JonBJ 1 Reply Last reply
        0
        • V Venkateswaran

          @JonB Thanks for clarifying this. Now I have another problem, on the server-side, I need to call another function with received test string from the client. I have tested the readAll() and as you said I'm receiving 130 bytes all at once (which is 5 times my test string). So how do I separate on server-side? I'm using QDataStream on client-side to send data and is there an elegant way to decouple the received bytes at server-side with QDataStream? maybe its a really basic question but it would be helpful for me if you show some example.

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

          @Venkateswaran
          Start by: have you read (and understood!) all the detail in https://doc.qt.io/qt-5/qdatastream.html#details ? And do look at subsection https://doc.qt.io/qt-5/qdatastream.html#using-read-transactions, because you may be looking for that.

          How is the client sending? ("I'm using QDataStream on client-side to send data" --- with just which calls on what data object types?) If you are using QDataStream at client send you will want QDataStream at server receive. And just btw: when you talk sometimes about "bytes" and sometimes about "string" do you indeed want QDataStream or did you maybe want QTextStream?

          1 Reply Last reply
          2
          • JonBJ JonB

            @Venkateswaran
            And it absolutely is not! :)

            • readyRead fires when there is at least 1 byte available.
            • readAll reads all that happens to be there when it is called. Anything ranging from 0 bytes to every byte sent!
            • readyRead won't fire again till you've done a readAll.

            That's it. No one-to-one. Your job to buffer received data at receiver, or split it up, if that's what you want to do.

            V Offline
            V Offline
            Venkateswaran
            wrote on last edited by
            #9

            @JonB also should i need to call m_socket->waitForBytesWritten(); at client side ?

            JonBJ 1 Reply Last reply
            0
            • V Venkateswaran

              @JonB also should i need to call m_socket->waitForBytesWritten(); at client side ?

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

              @Venkateswaran
              Nope :) Not unless you want to, it just stops client proceeding to the next line of code till bytes are written. But it makes no difference to the protocol/behaviour. And no effect at server-side.

              V 1 Reply Last reply
              0
              • JonBJ JonB

                @Venkateswaran
                Nope :) Not unless you want to, it just stops client proceeding to the next line of code till bytes are written. But it makes no difference to the protocol/behaviour. And no effect at server-side.

                V Offline
                V Offline
                Venkateswaran
                wrote on last edited by
                #11

                @JonB Thanks for the information. I want to send Boolean, Number, String from the client so DataStream would be the right one.
                This is how I'm sending data from the client :

                void TestClient::sendDataToServer() {
                    QByteArray block;
                    QDataStream out(&block, QIODevice::WriteOnly);
                    out.setVersion(QDataStream::Qt_5_10);
                    QString testString = "test data";
                    out << quint32(testString.size());
                    out << testString;
                    m_socket->write(block);
                    m_socket->flush();
                }
                

                This is what I tried at the server side to receive data (and it work for this basic example).

                void TestServer::onNewData() {
                    QLocalSocket* client = qobject_cast<QLocalSocket*>(sender());
                    qCritical() << "TestServer::onNewData" << client->bytesAvailable();
                    QDataStream in;
                    in.setDevice(client);
                    in.setVersion(QDataStream::Qt_5_10);
                    quint32 blockSize = 0;
                    QString test;
                
                    while(client->bytesAvailable() > (int)sizeof(quint32)) {
                        in >> blockSize;
                        if (client->bytesAvailable() < blockSize || in.atEnd()) return;
                        in >> test;
                        qDebug() << test << "printing received value";
                    }
                    qCritical() << "data read by server";
                }
                

                But looks like This Answer has a nice example to start with

                JonBJ 1 Reply Last reply
                0
                • V Venkateswaran

                  @JonB Thanks for the information. I want to send Boolean, Number, String from the client so DataStream would be the right one.
                  This is how I'm sending data from the client :

                  void TestClient::sendDataToServer() {
                      QByteArray block;
                      QDataStream out(&block, QIODevice::WriteOnly);
                      out.setVersion(QDataStream::Qt_5_10);
                      QString testString = "test data";
                      out << quint32(testString.size());
                      out << testString;
                      m_socket->write(block);
                      m_socket->flush();
                  }
                  

                  This is what I tried at the server side to receive data (and it work for this basic example).

                  void TestServer::onNewData() {
                      QLocalSocket* client = qobject_cast<QLocalSocket*>(sender());
                      qCritical() << "TestServer::onNewData" << client->bytesAvailable();
                      QDataStream in;
                      in.setDevice(client);
                      in.setVersion(QDataStream::Qt_5_10);
                      quint32 blockSize = 0;
                      QString test;
                  
                      while(client->bytesAvailable() > (int)sizeof(quint32)) {
                          in >> blockSize;
                          if (client->bytesAvailable() < blockSize || in.atEnd()) return;
                          in >> test;
                          qDebug() << test << "printing received value";
                      }
                      qCritical() << "data read by server";
                  }
                  

                  But looks like This Answer has a nice example to start with

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

                  @Venkateswaran
                  Note that the link you reference (by @VRonin) uses the transactions I suggested earlier: https://doc.qt.io/qt-5/qdatastream.html#using-read-transactions. No bytesAvailable() or buffering. Up to you.

                  1 Reply Last reply
                  3
                  • JonBJ JonB

                    @Venkateswaran
                    And it absolutely is not! :)

                    • readyRead fires when there is at least 1 byte available.
                    • readAll reads all that happens to be there when it is called. Anything ranging from 0 bytes to every byte sent!
                    • readyRead won't fire again till you've done a readAll.

                    That's it. No one-to-one. Your job to buffer received data at receiver, or split it up, if that's what you want to do.

                    VRoninV Offline
                    VRoninV Offline
                    VRonin
                    wrote on last edited by
                    #13

                    @JonB said in problem with QLocalSocket sending continues data to QLocalServer:

                    readyRead won't fire again till you've done a readAll.

                    This is not correct. From https://doc.qt.io/qt-5/qabstractsocket.html

                    The readyRead() signal is emitted every time a new chunk of data has arrived.

                    So it doesn't care whether you read the data or not


                    I suggest having a look at this article it uses QTcpSocket but the code is exactly the same for QLocalSocket. I'd focus on the ChatClient::onReadyRead method and its explanation below

                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                    ~Napoleon Bonaparte

                    On a crusade to banish setIndexWidget() from the holy land of Qt

                    JonBJ 1 Reply Last reply
                    3
                    • VRoninV VRonin

                      @JonB said in problem with QLocalSocket sending continues data to QLocalServer:

                      readyRead won't fire again till you've done a readAll.

                      This is not correct. From https://doc.qt.io/qt-5/qabstractsocket.html

                      The readyRead() signal is emitted every time a new chunk of data has arrived.

                      So it doesn't care whether you read the data or not


                      I suggest having a look at this article it uses QTcpSocket but the code is exactly the same for QLocalSocket. I'd focus on the ChatClient::onReadyRead method and its explanation below

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

                      @VRonin said in problem with QLocalSocket sending continues data to QLocalServer:

                      This is not correct.

                      Damn, and sorry! I thought that it had said that, but not. I may have confused with

                      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 (although waitForReadyRead() may still return true).

                      1 Reply Last reply
                      0

                      • Login

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