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

problem with QLocalSocket sending continues data to QLocalServer

Scheduled Pinned Locked Moved Solved General and Desktop
qlocalsocketqlocalserverreadyread
14 Posts 4 Posters 2.8k 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.
  • J JonB
    30 Oct 2020, 14:55

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

    Sever only gets the first data and not receiving subsequent data,

    How are you sure? You do not debug out the content/length of client->readAll();, so you don't know. My guess is: you assume a readAll() or onNewData signal correspond one-to-one with write/flish from client. But they don't. Your "1 msec delay" will make that true, probably, which is why you think you need that. You don't.

    V Offline
    V Offline
    Venkateswaran
    wrote on 30 Oct 2020, 14:57 last edited by
    #4

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

    C J 2 Replies Last reply 30 Oct 2020, 14:58
    0
    • V Venkateswaran
      30 Oct 2020, 14:57

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

      C Offline
      C Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 30 Oct 2020, 14:58 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
        30 Oct 2020, 14:57

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

        J Offline
        J Offline
        JonB
        wrote on 30 Oct 2020, 15:00 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 V 3 Replies Last reply 30 Oct 2020, 15:08
        0
        • J JonB
          30 Oct 2020, 15:00

          @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 30 Oct 2020, 15:08 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.

          J 1 Reply Last reply 30 Oct 2020, 15:15
          0
          • V Venkateswaran
            30 Oct 2020, 15:08

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

            J Offline
            J Offline
            JonB
            wrote on 30 Oct 2020, 15:15 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
            • J JonB
              30 Oct 2020, 15:00

              @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 30 Oct 2020, 15:20 last edited by
              #9

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

              J 1 Reply Last reply 30 Oct 2020, 15:24
              0
              • V Venkateswaran
                30 Oct 2020, 15:20

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

                J Offline
                J Offline
                JonB
                wrote on 30 Oct 2020, 15:24 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 30 Oct 2020, 15:31
                0
                • J JonB
                  30 Oct 2020, 15:24

                  @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 30 Oct 2020, 15:31 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

                  J 1 Reply Last reply 30 Oct 2020, 15:33
                  0
                  • V Venkateswaran
                    30 Oct 2020, 15:31

                    @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

                    J Offline
                    J Offline
                    JonB
                    wrote on 30 Oct 2020, 15:33 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
                    • J JonB
                      30 Oct 2020, 15:00

                      @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
                      VRonin
                      wrote on 30 Oct 2020, 16:22 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

                      J 1 Reply Last reply 30 Oct 2020, 17:05
                      3
                      • V VRonin
                        30 Oct 2020, 16:22

                        @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

                        J Offline
                        J Offline
                        JonB
                        wrote on 30 Oct 2020, 17:05 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

                        13/14

                        30 Oct 2020, 16:22

                        • Login

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