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. How to receive data in order from TCP server ?
Forum Updated to NodeBB v4.3 + New Features

How to receive data in order from TCP server ?

Scheduled Pinned Locked Moved Solved General and Desktop
4 Posts 3 Posters 546 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    TokaraForest
    wrote on last edited by
    #1

    Hello,

    I have a TCP client application that send and receive data successfully. First I send read request with packet that includes command id and data to server application. If server side processes this packet successfully, it sends a response packet that includes same command id and expected data.
    When I receive data in readyRead slot function, I set the related points in GUI ((assume I have value1, value2 variables defined in widget.h)):

    void Widget::readSocket()
    {
        QByteArray buffer;
    
        buffer = tcpSocket->readAll();
        // Some parsing operation to extract data from buffer to set value1
        //
        ui->labelValue1->setText(QString::number(value1));
    
    }
    

    To read all incoming data periodically (on every 1 second), I want to implement update function in QTimer's timeout function like this :

    void Widget::update()
    {
        readValue1();
        ui->labelValue1->setText(QString::number(value1));
    
        readValue2();
        ui->labelValue2->setText(QString::number(value2));
    
        .
        .
        .
    }
    

    To read values sequentially, I am planning to implement a blocking structure by using waitForReceivedData(int timeoutInMs) function. If the expected value is observed in determined timeout period, I can set a flag and proceed to next reading operation :

    void Widget::update()
    {
        readValue1();
        waitForReceivedData(100);
        ui->labelValue1->setText(QString::number(value1));
    
        readValue2();
        waitForReceivedData(100);
        ui->labelValue2->setText(QString::number(value2));
    
        .
        .
        .
    }
    

    The thing is, I can receive different values externally besides update() function(with a push button) and these values may interfere in readSocket() function. Therefore, I may read wrong values in update() function.

    I need to receive data in order in readyRead() function so that I can read true values in both update() function or other external events. When I researched about this, I encountered topics such as threads, queue etc. Maybe I can use a kind of lock mechanism or queue by using command id in packet that I send & receive.

    What is the proper way to handle this ? I am kind of new to Qt so I will be very appreciated if you could help me

    Regards

    JonBJ 1 Reply Last reply
    0
    • T TokaraForest

      Hello,

      I have a TCP client application that send and receive data successfully. First I send read request with packet that includes command id and data to server application. If server side processes this packet successfully, it sends a response packet that includes same command id and expected data.
      When I receive data in readyRead slot function, I set the related points in GUI ((assume I have value1, value2 variables defined in widget.h)):

      void Widget::readSocket()
      {
          QByteArray buffer;
      
          buffer = tcpSocket->readAll();
          // Some parsing operation to extract data from buffer to set value1
          //
          ui->labelValue1->setText(QString::number(value1));
      
      }
      

      To read all incoming data periodically (on every 1 second), I want to implement update function in QTimer's timeout function like this :

      void Widget::update()
      {
          readValue1();
          ui->labelValue1->setText(QString::number(value1));
      
          readValue2();
          ui->labelValue2->setText(QString::number(value2));
      
          .
          .
          .
      }
      

      To read values sequentially, I am planning to implement a blocking structure by using waitForReceivedData(int timeoutInMs) function. If the expected value is observed in determined timeout period, I can set a flag and proceed to next reading operation :

      void Widget::update()
      {
          readValue1();
          waitForReceivedData(100);
          ui->labelValue1->setText(QString::number(value1));
      
          readValue2();
          waitForReceivedData(100);
          ui->labelValue2->setText(QString::number(value2));
      
          .
          .
          .
      }
      

      The thing is, I can receive different values externally besides update() function(with a push button) and these values may interfere in readSocket() function. Therefore, I may read wrong values in update() function.

      I need to receive data in order in readyRead() function so that I can read true values in both update() function or other external events. When I researched about this, I encountered topics such as threads, queue etc. Maybe I can use a kind of lock mechanism or queue by using command id in packet that I send & receive.

      What is the proper way to handle this ? I am kind of new to Qt so I will be very appreciated if you could help me

      Regards

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @TokaraForest
      In outline, this is not the way to approach things in an event-driven UI system such as Qt. You ought not be attempting to sequentially read data and act on it they way you show. Better is to allow data to arrive and act on what you get when you get it.

      Basically you don't want to use any waitFor...() functions. They end up blocking the UI. Rather than readSocket() directly doing UI updates, it should just append what it receives into a buffer, and emit a signal whenever a full "instruction" is received completely, however that is defined. A slot on that signal can then "parse" the latest complete data and, say update a single item in the UI. And so on. No "waiting".

      Are you in charge of the server-side? The responses it sends should be "marked" so the client knows when the message is complete, e.g. perhaps is sends lines ending in \n? That is much better then trying to use timers to calculate when you must have received a full "packet".

      T 1 Reply Last reply
      2
      • JonBJ JonB

        @TokaraForest
        In outline, this is not the way to approach things in an event-driven UI system such as Qt. You ought not be attempting to sequentially read data and act on it they way you show. Better is to allow data to arrive and act on what you get when you get it.

        Basically you don't want to use any waitFor...() functions. They end up blocking the UI. Rather than readSocket() directly doing UI updates, it should just append what it receives into a buffer, and emit a signal whenever a full "instruction" is received completely, however that is defined. A slot on that signal can then "parse" the latest complete data and, say update a single item in the UI. And so on. No "waiting".

        Are you in charge of the server-side? The responses it sends should be "marked" so the client knows when the message is complete, e.g. perhaps is sends lines ending in \n? That is much better then trying to use timers to calculate when you must have received a full "packet".

        T Offline
        T Offline
        TokaraForest
        wrote on last edited by
        #3

        @JonB Thank you for your suggestion. I have followed the steps you mentioned.

        @JonB said in How to receive data in order from TCP server ?:

        Are you in charge of the server-side? The responses it sends should be "marked" so the client knows when the message is complete, e.g. perhaps is sends lines ending in \n? That is much better then trying to use timers to calculate when you must have received a full "packet".

        Yes, I'm in charge of server side. I decide if the message is complete or not according to data length that server side sends.

        But I still need to send multiple read requests periodically. Let's say I have to read 10 different values every 1 second (period isn't critical right now, it can be 3 or 5 seconds). Should I call read request related functions sequentially like in update function I mentioned (without waitFor...() functions) ? Is there a better way to do that ?

        Kent-DorfmanK 1 Reply Last reply
        0
        • T TokaraForest

          @JonB Thank you for your suggestion. I have followed the steps you mentioned.

          @JonB said in How to receive data in order from TCP server ?:

          Are you in charge of the server-side? The responses it sends should be "marked" so the client knows when the message is complete, e.g. perhaps is sends lines ending in \n? That is much better then trying to use timers to calculate when you must have received a full "packet".

          Yes, I'm in charge of server side. I decide if the message is complete or not according to data length that server side sends.

          But I still need to send multiple read requests periodically. Let's say I have to read 10 different values every 1 second (period isn't critical right now, it can be 3 or 5 seconds). Should I call read request related functions sequentially like in update function I mentioned (without waitFor...() functions) ? Is there a better way to do that ?

          Kent-DorfmanK Offline
          Kent-DorfmanK Offline
          Kent-Dorfman
          wrote on last edited by
          #4

          @TokaraForest
          In addition to @JonB comments, understand that TCP is always "in order" because it is a stream transport. data is possibly fragmented by the network but is received and assembled in its transmitted order. You don't see the latter parts of the stream until all previous chunks have been received and inserted in the buffer.

          It seem what you're really asking about is transaction ordering, and that's up to the application as to how you do it. Please make sure to well define a transaction for your protocol. Ambiguities in the "state machine" between client and server will bite you.

          1 Reply Last reply
          3
          • T TokaraForest has marked this topic as solved on

          • Login

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