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
QtWS25 Last Chance

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 Offline
    L Offline
    lolopolosko
    wrote on 24 Jun 2016, 09:40 last edited by
    #1

    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 1 Reply Last reply 24 Jun 2016, 09:43
    0
    • 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?

            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

                                  7/16

                                  24 Jun 2016, 10:53

                                  • Login

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