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. QLocalSocket multiple messages

QLocalSocket multiple messages

Scheduled Pinned Locked Moved Solved General and Desktop
qlocalsocketservicewindows
16 Posts 5 Posters 7.3k 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.
  • L lolopolosko
    24 Jun 2016, 10:42

    @kshegunov

    m_block = m_block.append(bytes);
    

    I used it because some messages has bigger than 4096 bytes data
    And QLocalSocket divided this message on small parts

    Is it possible you don't receive the whole message and it's somehow discarded?
    Maybe. But how can I know this?

    How I can debug QLocalSocket between two processes?

    J Offline
    J Offline
    jsulm
    Lifetime Qt Champion
    wrote on 24 Jun 2016, 10:52 last edited by
    #6

    @lolopolosko m_block.append(bytes); is enough no need to assign it to itself

    https://forum.qt.io/topic/113070/qt-code-of-conduct

    1 Reply Last reply
    2
    • V Offline
      V Offline
      VRonin
      wrote on 24 Jun 2016, 10:53 last edited by
      #7

      you should check for m_socket->bytesAvailable() before calling QByteArray bytes = m_socket->readAll();

      The idea is that the packet has it's size as header (as quint32 for example), so check until bytesAvailable is at least the size of the header, read it and wait until bytesAvailable becomes equal to the size you receive

      By wait I mean return

      "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

      L 1 Reply Last reply 24 Jun 2016, 11:05
      2
      • V VRonin
        24 Jun 2016, 10:53

        you should check for m_socket->bytesAvailable() before calling QByteArray bytes = m_socket->readAll();

        The idea is that the packet has it's size as header (as quint32 for example), so check until bytesAvailable is at least the size of the header, read it and wait until bytesAvailable becomes equal to the size you receive

        By wait I mean return

        L Offline
        L Offline
        lolopolosko
        wrote on 24 Jun 2016, 11:05 last edited by
        #8

        @VRonin said:

        you should check for m_socket->bytesAvailable() before calling QByteArray bytes = m_socket->readAll();

        The idea is that the packet has it's size as header (as quint32 for example), so check until bytesAvailable is at least the size of the header, read it and wait until bytesAvailable becomes equal to the size you receive

        By wait I mean return

        See Client::receivedMessage

        void Client::receivedMessage() {
        // Read all data
            QByteArray bytes = m_socket->readAll();
            QDataStream stream(bytes);
            stream.setVersion(QDataStream::Qt_5_5);
        
        // Read header (quint32)
            if (m_blockSize == 0) {
                if (bytes.size() < (int)sizeof(quint32)) {
                    qDebug() << "Client::receivedMessage: Message is small than quint32";
                    return;
                }
        
                stream >> m_blockSize;
            }
        
        // Read data until m_block.size() == m_blockSize
            if (m_block.isEmpty()) {
                m_block = bytes;
            } else {
                m_block = m_block.append(bytes);
            }
        
            if (m_block.size() < m_blockSize) {
                qDebug() << "Client::receivedMessage: Message is smaller than block size";
                return;
            } else {
                m_blockSize = 0;
                LocalMessage msg = LocalMessage::fromByteArray(m_block, m_socket->socketDescriptor());
                emit message(msg);
                m_block.clear();
            }
        }
        

        But I dont use bytesAvailable() (because I use header (m_blockSize))

        K 1 Reply Last reply 24 Jun 2016, 11:14
        0
        • L lolopolosko
          24 Jun 2016, 11:05

          @VRonin said:

          you should check for m_socket->bytesAvailable() before calling QByteArray bytes = m_socket->readAll();

          The idea is that the packet has it's size as header (as quint32 for example), so check until bytesAvailable is at least the size of the header, read it and wait until bytesAvailable becomes equal to the size you receive

          By wait I mean return

          See Client::receivedMessage

          void Client::receivedMessage() {
          // Read all data
              QByteArray bytes = m_socket->readAll();
              QDataStream stream(bytes);
              stream.setVersion(QDataStream::Qt_5_5);
          
          // Read header (quint32)
              if (m_blockSize == 0) {
                  if (bytes.size() < (int)sizeof(quint32)) {
                      qDebug() << "Client::receivedMessage: Message is small than quint32";
                      return;
                  }
          
                  stream >> m_blockSize;
              }
          
          // Read data until m_block.size() == m_blockSize
              if (m_block.isEmpty()) {
                  m_block = bytes;
              } else {
                  m_block = m_block.append(bytes);
              }
          
              if (m_block.size() < m_blockSize) {
                  qDebug() << "Client::receivedMessage: Message is smaller than block size";
                  return;
              } else {
                  m_blockSize = 0;
                  LocalMessage msg = LocalMessage::fromByteArray(m_block, m_socket->socketDescriptor());
                  emit message(msg);
                  m_block.clear();
              }
          }
          

          But I dont use bytesAvailable() (because I use header (m_blockSize))

          K Offline
          K Offline
          kshegunov
          Moderators
          wrote on 24 Jun 2016, 11:14 last edited by
          #9

          @lolopolosko
          The point is, that this:

          if (bytes.size() < (int)sizeof(quint32)) {
              qDebug() << "Client::receivedMessage: Message is small than quint32";
              return;
          }
          

          will make you skip a message if you don't receive the integer whole (i.e. the 4 bytes at once). It's somewhat unusual to get so little data, but certainly not impossible. Also casting sizeof doesn't really make any sense. sizeof is not a function, but it's a language construct that will be substituted by the compiler with the proper number when generating the binary ...

          Read and abide by the Qt Code of Conduct

          L 1 Reply Last reply 24 Jun 2016, 11:18
          1
          • K kshegunov
            24 Jun 2016, 11:14

            @lolopolosko
            The point is, that this:

            if (bytes.size() < (int)sizeof(quint32)) {
                qDebug() << "Client::receivedMessage: Message is small than quint32";
                return;
            }
            

            will make you skip a message if you don't receive the integer whole (i.e. the 4 bytes at once). It's somewhat unusual to get so little data, but certainly not impossible. Also casting sizeof doesn't really make any sense. sizeof is not a function, but it's a language construct that will be substituted by the compiler with the proper number when generating the binary ...

            L Offline
            L Offline
            lolopolosko
            wrote on 24 Jun 2016, 11:18 last edited by
            #10

            @kshegunov
            Yes, I know...

            But wait :-)
            I redirect qDebug() to a file, and when I read logs, I dont find message "Client::receivedMessage: Message is small than quint32";

            K 1 Reply Last reply 24 Jun 2016, 11:26
            0
            • L lolopolosko
              24 Jun 2016, 11:18

              @kshegunov
              Yes, I know...

              But wait :-)
              I redirect qDebug() to a file, and when I read logs, I dont find message "Client::receivedMessage: Message is small than quint32";

              K Offline
              K Offline
              kshegunov
              Moderators
              wrote on 24 Jun 2016, 11:26 last edited by
              #11

              @lolopolosko
              Well your code looks pretty okay, so if I were you I'd focus my efforts on:

              LocalMessage::fromByteArray(m_block, m_socket->socketDescriptor());
              

              There's one thing that also caught my eye, you do realize you're including the header size field (the thing you read in m_blockSize) in the m_block buffer, right?

              I still may be missing some subtlety, but currently I don't see anything that's plainly wrong.

              Kind regards.

              Read and abide by the Qt Code of Conduct

              L 1 Reply Last reply 24 Jun 2016, 14:33
              1
              • K kshegunov
                24 Jun 2016, 11:26

                @lolopolosko
                Well your code looks pretty okay, so if I were you I'd focus my efforts on:

                LocalMessage::fromByteArray(m_block, m_socket->socketDescriptor());
                

                There's one thing that also caught my eye, you do realize you're including the header size field (the thing you read in m_blockSize) in the m_block buffer, right?

                I still may be missing some subtlety, but currently I don't see anything that's plainly wrong.

                Kind regards.

                L Offline
                L Offline
                lolopolosko
                wrote on 24 Jun 2016, 14:33 last edited by lolopolosko
                #12

                @kshegunov
                Ok.. Now I changed source code for debugging

                I send message directly from my service (without queue)
                When client started, service send next messages
                TypeMessage::Setting1
                TypeMessage::Setting2
                TypeMessage::Setting3
                TypeMessage::Setting4
                TypeMessage::Setting5
                TypeMessage::Setting6
                TypeMessage::Setting7

                And client received only next messages:
                TypeMessage::Setting1
                TypeMessage::Setting2
                TypeMessage::Setting4

                For Client::receivedMessage method I put at the beginning of a method

                qDebug() << "Client::receivedMessage: bytesAvailable" << m_socket->bytesAvailable();
                

                Now I see in log file

                17:22:14:457 - Client::receivedMessage: bytesAvailable 5243
                17:22:14:457 - ClientController::onSocketMessageReceived: TypeMessage::Setting1
                17:22:14:495 - Client::receivedMessage: bytesAvailable 187
                17:22:14:495 - ClientController::onSocketMessageReceived: TypeMessage:Setting2
                17:22:14:496 - Client::receivedMessage: bytesAvailable 572
                17:22:14:496 - ClientController::onSocketMessageReceived: TypeMessage:Setting4
                

                But where is another messages I dont know

                If I use message queue in Service, I receive all messages (but sometimes some messages lost)

                I think problem in Service method

                void LocalServer::postData(LocalMessage& message) {
                    QByteArray bytes = message.toByteArray();
                
                    if (m_sockets.contains(message.socketDescription)) {
                        if (m_sockets[message.socketDescription]->state() == QLocalSocket::ConnectedState) {
                            m_sockets[message.socketDescription]->write(bytes);
                            m_sockets[message.socketDescription]->flush();
                        } else {
                            qDebug() << "LocalServer::postData: Socket cannot connected to the server. Current state of socket" << (int)m_sockets[message.socketDescription]->state();
                            emit error("Socket unconected");
                        }
                    } else {
                        qDebug() << "LocalServer::postData: Socket with descriptor" << message.socketDescription << "not found";
                        emit error("Not found socket");
                    }
                }
                
                K 1 Reply Last reply 24 Jun 2016, 15:30
                0
                • L lolopolosko
                  24 Jun 2016, 14:33

                  @kshegunov
                  Ok.. Now I changed source code for debugging

                  I send message directly from my service (without queue)
                  When client started, service send next messages
                  TypeMessage::Setting1
                  TypeMessage::Setting2
                  TypeMessage::Setting3
                  TypeMessage::Setting4
                  TypeMessage::Setting5
                  TypeMessage::Setting6
                  TypeMessage::Setting7

                  And client received only next messages:
                  TypeMessage::Setting1
                  TypeMessage::Setting2
                  TypeMessage::Setting4

                  For Client::receivedMessage method I put at the beginning of a method

                  qDebug() << "Client::receivedMessage: bytesAvailable" << m_socket->bytesAvailable();
                  

                  Now I see in log file

                  17:22:14:457 - Client::receivedMessage: bytesAvailable 5243
                  17:22:14:457 - ClientController::onSocketMessageReceived: TypeMessage::Setting1
                  17:22:14:495 - Client::receivedMessage: bytesAvailable 187
                  17:22:14:495 - ClientController::onSocketMessageReceived: TypeMessage:Setting2
                  17:22:14:496 - Client::receivedMessage: bytesAvailable 572
                  17:22:14:496 - ClientController::onSocketMessageReceived: TypeMessage:Setting4
                  

                  But where is another messages I dont know

                  If I use message queue in Service, I receive all messages (but sometimes some messages lost)

                  I think problem in Service method

                  void LocalServer::postData(LocalMessage& message) {
                      QByteArray bytes = message.toByteArray();
                  
                      if (m_sockets.contains(message.socketDescription)) {
                          if (m_sockets[message.socketDescription]->state() == QLocalSocket::ConnectedState) {
                              m_sockets[message.socketDescription]->write(bytes);
                              m_sockets[message.socketDescription]->flush();
                          } else {
                              qDebug() << "LocalServer::postData: Socket cannot connected to the server. Current state of socket" << (int)m_sockets[message.socketDescription]->state();
                              emit error("Socket unconected");
                          }
                      } else {
                          qDebug() << "LocalServer::postData: Socket with descriptor" << message.socketDescription << "not found";
                          emit error("Not found socket");
                      }
                  }
                  
                  K Offline
                  K Offline
                  kshegunov
                  Moderators
                  wrote on 24 Jun 2016, 15:30 last edited by kshegunov
                  #13

                  @lolopolosko
                  Could you humor me and output both m_blockSize with m_socket->bytesAvailable() side by side?

                  Read and abide by the Qt Code of Conduct

                  L 2 Replies Last reply 25 Jun 2016, 19:41
                  1
                  • K kshegunov
                    24 Jun 2016, 15:30

                    @lolopolosko
                    Could you humor me and output both m_blockSize with m_socket->bytesAvailable() side by side?

                    L Offline
                    L Offline
                    lolopolosko
                    wrote on 25 Jun 2016, 19:41 last edited by lolopolosko
                    #14

                    @kshegunov
                    Hey!! You're right ^_^
                    But I don't understand.. How it possible??

                    My new log:

                    I: 22:36:04:211 - Client::receivedMessage: bytesAvailable 6015
                    I: 22:36:04:213 - Client::receivedMessage: m_blockSize 6011
                    I: 22:36:04:216 - ClientController::onSocketMessageReceived: TypeMessage::Setting1
                    I: 22:36:04:255 - Client::receivedMessage: bytesAvailable 337
                    I: 22:36:04:257 - Client::receivedMessage: m_blockSize 235
                    I: 22:36:04:259 - ClientController::onSocketMessageReceived: TypeMessage:Setting2
                    I: 22:36:04:261 - Client::receivedMessage: bytesAvailable 1008
                    I: 22:36:04:263 - Client::receivedMessage: m_blockSize 334
                    I: 22:36:04:265 - ClientController::onSocketMessageReceived: TypeMessage:Setting4
                    

                    QLocalSocket merge data? And how I can unmerge it?
                    Now I don't understand how it works... :-(

                    P.S.
                    When readyRead is called, the might be more than one message to be read.

                    1 Reply Last reply
                    0
                    • K kshegunov
                      24 Jun 2016, 15:30

                      @lolopolosko
                      Could you humor me and output both m_blockSize with m_socket->bytesAvailable() side by side?

                      L Offline
                      L Offline
                      lolopolosko
                      wrote on 26 Jun 2016, 19:28 last edited by
                      #15

                      Ok.. I fix it!
                      @kshegunov Thank you very much!

                      Now I added \x1C character (INFORMATION SEPARATOR FOUR) at the end message
                      When client reads data it check if bytesAvailable > m_blockSize and if it true I split data by \x1C character.

                      K 1 Reply Last reply 26 Jun 2016, 19:39
                      0
                      • L lolopolosko
                        26 Jun 2016, 19:28

                        Ok.. I fix it!
                        @kshegunov Thank you very much!

                        Now I added \x1C character (INFORMATION SEPARATOR FOUR) at the end message
                        When client reads data it check if bytesAvailable > m_blockSize and if it true I split data by \x1C character.

                        K Offline
                        K Offline
                        kshegunov
                        Moderators
                        wrote on 26 Jun 2016, 19:39 last edited by
                        #16

                        @lolopolosko
                        Oh, I was just about to suggest you buffer all the received data. But as you've solved your problem then my suggestion is moot. I'm glad it works now.

                        Kind regards.

                        Read and abide by the Qt Code of Conduct

                        1 Reply Last reply
                        0

                        15/16

                        26 Jun 2016, 19:28

                        • Login

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