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 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
          • VRoninV Offline
            VRoninV 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
            • VRoninV 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

                              12/16

                              24 Jun 2016, 14:33

                              • Login

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