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.
  • K kshegunov
    24 Jun 2016, 10:19

    @lolopolosko
    Hello,
    Is it possible you don't receive the whole message and it's somehow discarded?
    By the way, this:

    m_block = m_block.append(bytes);
    

    looks pretty suspicious by itself.

    L Offline
    L Offline
    lolopolosko
    wrote on 24 Jun 2016, 10:42 last edited by
    #5

    @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 1 Reply Last reply 24 Jun 2016, 10:52
    0
    • 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

                          14/16

                          25 Jun 2016, 19:41

                          • Login

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