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. [SOLVED] reading data in QTCPsocket is incomplete
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] reading data in QTCPsocket is incomplete

Scheduled Pinned Locked Moved General and Desktop
14 Posts 3 Posters 9.7k 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.
  • IamSumitI Offline
    IamSumitI Offline
    IamSumit
    wrote on last edited by
    #3

    Hello Marty,
    When you write your data on socket you use socket->write() function.
    It returns no of bytes written to a socket if your data is written completely then there is no problem on writing side.
    Check it out using qDebug().

    Be Cute

    1 Reply Last reply
    0
    • M Offline
      M Offline
      Marty
      wrote on last edited by
      #4

      Hi and thank you for your suggestions !

      the thing is :

      • the server is a device and i don't have much information about the TCP message format for the answer. The only thing i know is the response message is composed of :

      • the command the device received + EOL (CR/LF)

      • the answer to the query, here this is the message stored in memory + EOL (CR/LF)

      • state of execution (valid or not) + EOL (CR/LF)

      it would be great if the device sends the message size in the TCP frame but i don't have this information.

      So i don't know how to be sure i read all data !

      I will try to get the number of bytes written to the device as suggested.

      Could the EOL (CR/LF) be a problem when reveiving TCP packets ?
      How can i handle this ?

      thanks a lot

      1 Reply Last reply
      0
      • Q Offline
        Q Offline
        qxoz
        wrote on last edited by
        #5

        [quote author="Marty" date="1392894981"]

        • the command the device received + EOL (CR/LF)
        • the answer to the query, here this is the message stored in memory + EOL (CR/LF)
        • state of execution (valid or not) + EOL (CR/LF)
          [/quote]
          You already have enough information. Just wait until you receive all three parts of message which are ends with EOL.
        1 Reply Last reply
        0
        • M Offline
          M Offline
          Marty
          wrote on last edited by
          #6

          how would you write this part ?

          because in the documentation it says the response always ends with "@ + first letter of the command sent + state (like V for valid or E for error) + EOL".
          I tried to detect the character "@" yesterday just for a test purpose but my app froze like in infinite loop while waiting for that character that never arrives.

          Also, why when i send the command with telnet in a terminal i get the entire answer. How does telnet know when it gets the entire response ?

          thanks again

          1 Reply Last reply
          0
          • IamSumitI Offline
            IamSumitI Offline
            IamSumit
            wrote on last edited by
            #7

            @OK your server is a device ,the information you only know the composition of message as response from the server .
            Your problem is you are not getting full data from the server(Which is unknown to you) .
            You can use QQueue data structure -

            QQueue <QByteArray>Queue; (in .h file)

            QBytearray data=pSocket->readAll();
            qDebug() << "Data From Client : " << "\n\n" <<data;
            Queue.enqueue(data);

            while(!Queue.isEmpty())
            {
            QString str=Queue.dequeue();
            QString str=data;

                qdebug() << str ;
                   str.clear();
            

            }
            try it

            Be Cute

            1 Reply Last reply
            0
            • Q Offline
              Q Offline
              qxoz
              wrote on last edited by
              #8

              Use Wireshark, so you can see what exactly happening(what data sends by device) in network.
              And as IamSumit wrote using QQueue is good solution.

              1 Reply Last reply
              0
              • Q Offline
                Q Offline
                qxoz
                wrote on last edited by
                #9

                By the way
                can you show code how do you doing it?

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  Marty
                  wrote on last edited by
                  #10

                  yep. will have a look to QQueue.

                  here is some code.

                  When i clic a button :

                  @void ledBar::getStoredMessage(int bank)
                  {
                  QString message;
                  if (bank < 10)
                  {
                  message = sendQuery("COP0" + QString::number(bank) + "\r\n");
                  }
                  else
                  {
                  message = sendQuery("COP" + QString::number(bank) + "\r\n");
                  }
                  qDebug() << message;
                  }@

                  The sendQuery() Method :

                  @void TCPClient::sendQuery(QByteArray query)
                  {
                  if (socket->state() != QAbstractSocket::ConnectedState)
                  {
                  qWarning() << "Can't send command : not connected !";
                  }
                  else
                  {
                  socket->write(query)
                  }
                  }
                  @

                  then my readYread() slot :

                  @void TCPClient::readyRead()
                  {
                  if(socket->waitForBytesWritten(2000) && socket->waitForReadyRead((2000)))
                  {
                  timer->start(timeout);
                  return socket->readAll();
                  }
                  }@

                  1 Reply Last reply
                  0
                  • Q Offline
                    Q Offline
                    qxoz
                    wrote on last edited by
                    #11

                    Is your code compiled ok?
                    Anyway, let's change your code in following way:
                    Add some buffer variables in your class
                    @private:
                    //....
                    QString responseTempalte;
                    QByteArray incommingData;
                    bool isDataComplete;
                    //....@
                    change getStoredMessage(int bank)
                    @void ledBar::getStoredMessage(int bank)
                    {
                    QString message = QStringLiteral("COP%1\r\n").arg(bank, 2, 10, QChar('0'));
                    responseTempalte = QStringLiteral("@%1%2\r\n").arg(message.at(0));
                    incommingData.clear();
                    isDataComplete = false;
                    sendQuery(message.toLatin1());
                    qDebug() << message;
                    }@
                    and most important part, readyRead slot
                    @void TCPClient::readyRead()
                    {
                    incommingData.append(socket->readAll());
                    if(incommingData.contains(responseTempalte.arg("V")) ||
                    incommingData.contains(responseTempalte.arg("E")) )
                    {
                    isDataComplete = true;//or emit some signal
                    }
                    }@
                    something like that, i hope didn't forget something important.

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      Marty
                      wrote on last edited by
                      #12

                      Great i will give it a try !

                      maybe the best is, if you have time, to have a look at the whole project :

                      https://github.com/martialgallorini/ledManager

                      thanks a lot

                      1 Reply Last reply
                      0
                      • M Offline
                        M Offline
                        Marty
                        wrote on last edited by
                        #13

                        humm... can't make it to work

                        program without change compile and run well (except truncated TCP response)

                        i have applied the changes you suggested. It compiles ok, but when clic on send command button it freezes then close then crashes the app

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          Marty
                          wrote on last edited by
                          #14

                          Well i figured it out but i don't understand why !

                          With

                          [CODE]socket->readLine();[/CODE]

                          it reads each complete line.

                          I tried everything (read(), readAll()...) and NOTHING but readLine() works !
                          If anybody has a clue why readAll() does'nt make it here...

                          [CODE]
                          void TCPClient::readyRead()
                          {
                          if(socket->waitForReadyRead(2000))
                          {
                          QString resp;
                          while(socket->bytesAvailable() > 0)
                          {
                          resp.append(socket->readLine());
                          }
                          emit sigTcpDataReceived(resp.toUtf8());
                          }
                          else
                          {
                          qWarning() << "Waiting for data to read timed out. No data received !";
                          }
                          }
                          [/CODE]

                          Thank you very much to everybody and for your help !

                          1 Reply Last reply
                          0

                          • Login

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