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 3.3k 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.
  • JonBJ JonB

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

    Christian EhrlicherC JonBJ 2 Replies Last reply
    0
    • 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 Offline
      Christian EhrlicherC Offline
      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