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, 09:40

    Hello everyone

    I've got 2 applications. One client and the other Server (Windows Service)
    Service started and run client automaticly. When client started, it sent message to service that means "I'm running and send me data". Server receive this and send message (about 8-9) to client.
    Some messages has more data (10-20 KB) and some little.
    But when client received data, it lost some messages

    Example:
    From service I send next data
    One
    Two
    Three
    Four
    Five

    And client receive
    One
    Two
    Four
    Five

    I don't know why and how I can fix it...

    And after some time I created MessagesQueue.
    I post data (In service) into queue and timer (100msec) get 3 messages and send to client
    It works now.. But today I reproduce this problem again.. When my local machine freeze (because has a lot of work), I lost some messages.

    Can I fix it and how?

    R Offline
    R Offline
    raven-worx
    Moderators
    wrote on 24 Jun 2016, 09:43 last edited by
    #2

    @lolopolosko
    You can't expect someone to help you find a mistake in your code, without posting the actual code...

    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
    If you have a question please use the forum so others can benefit from the solution in the future

    1 Reply Last reply
    2
    • L Offline
      L Offline
      lolopolosko
      wrote on 24 Jun 2016, 09:49 last edited by
      #3
      // CLIENT
      void Client::init() {
              m_socket = new QLocalSocket(this);
              m_socket->setReadBufferSize(512000);
              connect(m_socket, SIGNAL(readyRead()), this, SLOT(receivedMessage()));
      }
      
      void Client::receivedMessage() {
          QByteArray bytes = m_socket->readAll();
          QDataStream stream(bytes);
          stream.setVersion(QDataStream::Qt_5_5);
      
          if (m_blockSize == 0) {
              if (bytes.size() < (int)sizeof(quint32)) {
                  qDebug() << "Client::receivedMessage: Message is small than quint32";
                  return;
              }
      
              stream >> 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();
          }
      }
      
      // SERVICE
      void LocalServer::init() {
          m_server = new QLocalServer(this);
          m_server->setSocketOptions(QLocalServer::OtherAccessOption);
      }
      
      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, 10:19
      0
      • L lolopolosko
        24 Jun 2016, 09:49
        // CLIENT
        void Client::init() {
                m_socket = new QLocalSocket(this);
                m_socket->setReadBufferSize(512000);
                connect(m_socket, SIGNAL(readyRead()), this, SLOT(receivedMessage()));
        }
        
        void Client::receivedMessage() {
            QByteArray bytes = m_socket->readAll();
            QDataStream stream(bytes);
            stream.setVersion(QDataStream::Qt_5_5);
        
            if (m_blockSize == 0) {
                if (bytes.size() < (int)sizeof(quint32)) {
                    qDebug() << "Client::receivedMessage: Message is small than quint32";
                    return;
                }
        
                stream >> 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();
            }
        }
        
        // SERVICE
        void LocalServer::init() {
            m_server = new QLocalServer(this);
            m_server->setSocketOptions(QLocalServer::OtherAccessOption);
        }
        
        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, 10:19 last edited by
        #4

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

        Read and abide by the Qt Code of Conduct

        L 1 Reply Last reply 24 Jun 2016, 10:42
        1
        • 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?

          jsulmJ 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?

            jsulmJ Offline
            jsulmJ 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

                                11/16

                                24 Jun 2016, 11:26

                                • Login

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