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
Forum Updated to NodeBB v4.3 + New Features

QLocalSocket multiple messages

Scheduled Pinned Locked Moved Solved General and Desktop
qlocalsocketservicewindows
16 Posts 5 Posters 7.4k Views 2 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 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

                      16/16

                      26 Jun 2016, 19:39

                      • Login

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