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. QTcpSocket: how to read numbers
QtWS25 Last Chance

QTcpSocket: how to read numbers

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 4 Posters 3.9k 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.
  • D Offline
    D Offline
    Davide87
    wrote on last edited by
    #1

    Dear all.
    It may look a very simple question, but I couldn't find any help in the qt documentation or in the web.
    All I want is to read a series of numbers (integers, double or whatever) from a TCP socket. Not strings.
    The TCP server is made in MatLab and it sends a series of numbers in double precision format (8 bytes).
    I used the readAll function to get the data and I got a QByteArray of N*8 elements (where N is the number of elements of the double array in MatLab).
    I can easily separate the N elements with the mid function, but after that how can I get the numbers from the 8-elements QByteArray object? If for example is write

    QByteArray myData;
    QByteArray myData_element;
    
    myData = socket->readAll(); //This one has N*8 elements
    myData_element = myData.mid(0,8); // This one has 8 elements
    
    qDebug() << myData_element.data();
    

    what I get is a series of strange characters.
    If the server sends one uint8 number, with

    qDebug() << myData_element.data();
    

    I get instead the acsii character relative to the number that is sent.
    I tried and tried but I can't obtain the number sent by the server (even the uint8).
    Actually, the fact that the TCP server is made in MatLab is not relevant. It may be made even in c++, but the I have the same issue if such server sends numbers in any format that is not a string.
    Do you have any suggestions?

    Thank you.

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi
      When you send binary data over the socket you will see the actual internal format.
      Hence you must convert it back to the real type.
      did you try
      bool ok;
      int data = myData_element.toInt(&ok,10);
      QByteArray contains many function to convert the buffer to real types. int/double etc.

      D 1 Reply Last reply
      1
      • mrjjM mrjj

        Hi
        When you send binary data over the socket you will see the actual internal format.
        Hence you must convert it back to the real type.
        did you try
        bool ok;
        int data = myData_element.toInt(&ok,10);
        QByteArray contains many function to convert the buffer to real types. int/double etc.

        D Offline
        D Offline
        Davide87
        wrote on last edited by Davide87
        #3

        @mrjj Yes, I tried. But the conversion fails (ok=false).
        If the server sends the number 65 (uint8) and I write the code

        bool ok;
        int number = myData_element.toInt(&ok,10);
        qDebug() << myData_element << myData_element.data() << number << ok;
        

        it will return:
        "A" A 0 false

        This is because the number 65 is related to the ascii character "A" and the toInt function will try to convert the character "A" to a number (and it will obviously fail).

        If instead it sends a double, single, int32, etc. it will display other characters and it will try to convert those characters to integers (or double) and fail.

        Instead, if the server sends 49, which is related to the ascii character "1", the function toInt will return the number 1 (and ok=true).

        1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by VRonin
          #4

          Use QDataStream but you have to check the endinannes. I don't know what matlab uses, QDataStream will use Big-Endian by default, just as Matlab does, but you can change it with QDataStream::setByteOrder

          QDataStream socketStream(socket);
          double tempNumber = 0.0;
          for(;;){
          socketStream.startTransaction();
          socketStream >> tempNumber;
          if(socketStream.commitTransaction())
          qDebug() << "Received: " << tempNumber;
          else
          break;
          }
          

          "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

          aha_1980A 1 Reply Last reply
          3
          • VRoninV VRonin

            Use QDataStream but you have to check the endinannes. I don't know what matlab uses, QDataStream will use Big-Endian by default, just as Matlab does, but you can change it with QDataStream::setByteOrder

            QDataStream socketStream(socket);
            double tempNumber = 0.0;
            for(;;){
            socketStream.startTransaction();
            socketStream >> tempNumber;
            if(socketStream.commitTransaction())
            qDebug() << "Received: " << tempNumber;
            else
            break;
            }
            
            aha_1980A Offline
            aha_1980A Offline
            aha_1980
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @VRonin

            During my studies, our professor told us that the "convention" on Ethernet is Big Endian, which was funny as almost all computers at that time used Intel aka Little Endian architecture.

            But this is no iron law, and I'm currently working with a customer that demanded a Little Endian protocol. Well, it's on a RS-422 line, which transfers data LSB first, so you can at least read your data backwards on the line :)

            Qt has to stay free or it will die.

            VRoninV 1 Reply Last reply
            1
            • aha_1980A aha_1980

              @VRonin

              During my studies, our professor told us that the "convention" on Ethernet is Big Endian, which was funny as almost all computers at that time used Intel aka Little Endian architecture.

              But this is no iron law, and I'm currently working with a customer that demanded a Little Endian protocol. Well, it's on a RS-422 line, which transfers data LSB first, so you can at least read your data backwards on the line :)

              VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by
              #6

              @aha_1980 said in QTcpSocket: how to read numbers:

              During my studies, our professor told us that the "convention" on Ethernet is Big Endian

              That was probably the same professor the guys at MathWorks had, from
              https://uk.mathworks.com/help/instrument/read-and-write-binary-data-over-tcpip.html :

              You may need to configure the ByteOrder of the TCP/IP object. The ByteOrder property specifies the byte order of the server. By default ByteOrder is bigEndian

              "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

              1 Reply Last reply
              1
              • D Offline
                D Offline
                Davide87
                wrote on last edited by
                #7

                It works. Thank you very much guys.

                At first I "fixed" it by using the QChar class and the unicode function to get the value of every single byte and combine them. But it was a very inelegant solution and gave problems with numbers greater than 127.
                I tried the QDataStream too but it didn't work. Simply because my knowledge in Qt is at very beginner level and I didn't know how to use the QDataStream properly. I didn't know about the startTransaction and commitTransaction functions.
                Now it works good. Thank you :-)

                aha_1980A 1 Reply Last reply
                1
                • D Davide87

                  It works. Thank you very much guys.

                  At first I "fixed" it by using the QChar class and the unicode function to get the value of every single byte and combine them. But it was a very inelegant solution and gave problems with numbers greater than 127.
                  I tried the QDataStream too but it didn't work. Simply because my knowledge in Qt is at very beginner level and I didn't know how to use the QDataStream properly. I didn't know about the startTransaction and commitTransaction functions.
                  Now it works good. Thank you :-)

                  aha_1980A Offline
                  aha_1980A Offline
                  aha_1980
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Hi @Davide87,

                  well it's possible without QDataStream also. The problem with numbers > 127 results from QByteArray consisting of chars which most compilers treat as signed unfortunately. that can be solved with casting to unsigned char.

                  Qt has to stay free or it will die.

                  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