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. Problem with a data from UDP
Forum Updated to NodeBB v4.3 + New Features

Problem with a data from UDP

Scheduled Pinned Locked Moved Solved General and Desktop
28 Posts 4 Posters 3.4k 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.
  • J Offline
    J Offline
    jenya7
    wrote on 8 Jul 2021, 10:20 last edited by jenya7 7 Aug 2021, 10:21
    #1

    I get some data

    socket->readDatagram(udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);
    

    but the first argument is a char.

    qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *host = nullptr, quint16 *port = nullptr);
    

    and I get bytes (uint8_t) - so my data will be trancated?

    J 1 Reply Last reply 8 Jul 2021, 10:28
    0
    • S Offline
      S Offline
      sierdzio
      Moderators
      wrote on 8 Jul 2021, 10:27 last edited by
      #2

      No, it won't. The first argument is a pointer which may point to a string of arbitrary length.

      But better just use receiveDatagram() https://doc.qt.io/qt-5/qudpsocket.html#receiveDatagram, with that function you can easily read the result as a QByteArray.

      (Z(:^

      1 Reply Last reply
      1
      • J jenya7
        8 Jul 2021, 10:20

        I get some data

        socket->readDatagram(udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);
        

        but the first argument is a char.

        qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *host = nullptr, quint16 *port = nullptr);
        

        and I get bytes (uint8_t) - so my data will be trancated?

        J Offline
        J Offline
        JonB
        wrote on 8 Jul 2021, 10:28 last edited by
        #3

        @jenya7 said in Problem with a data from UDP:

        but the first argument is a char.

        It isn't. It's a char *.

        and I get bytes (uint8_t)

        That will be: typedef unsigned char uint8_t;.

        Size is OK. There will be no "truncation". What type does your udp_buffer.data() return anyway?

        1 Reply Last reply
        1
        • J Offline
          J Offline
          jenya7
          wrote on 8 Jul 2021, 10:35 last edited by jenya7 7 Aug 2021, 10:36
          #4

          It's

          QByteArray udp_buffer;
          

          Now I pass it to a parse function

          uint32_t MSGPARSER::ParseMessage(QByteArray data, MESSAGE * sens_msg)  
          {
              if (data[0] == INTERFACE_ID_NONE || data[1] > INTERFACE_ID_RS485) // error: use of erloaded operator '==' is ambiguous (with operand types 'QByteRef' and 'int')
                  return MSG_PARSE_ERROR_WRONG_INTFACE_ID;
              else
                 sens_msg->interface_id = data[0];  // warning: implicit conversion changes signedness: 'char' to 'uint8_t' (aka 'unsigned char')
                    
              return 0;
          }
          

          So data[0] is a char.

          S 1 Reply Last reply 8 Jul 2021, 10:39
          0
          • J jenya7
            8 Jul 2021, 10:35

            It's

            QByteArray udp_buffer;
            

            Now I pass it to a parse function

            uint32_t MSGPARSER::ParseMessage(QByteArray data, MESSAGE * sens_msg)  
            {
                if (data[0] == INTERFACE_ID_NONE || data[1] > INTERFACE_ID_RS485) // error: use of erloaded operator '==' is ambiguous (with operand types 'QByteRef' and 'int')
                    return MSG_PARSE_ERROR_WRONG_INTFACE_ID;
                else
                   sens_msg->interface_id = data[0];  // warning: implicit conversion changes signedness: 'char' to 'uint8_t' (aka 'unsigned char')
                      
                return 0;
            }
            

            So data[0] is a char.

            S Offline
            S Offline
            sierdzio
            Moderators
            wrote on 8 Jul 2021, 10:39 last edited by
            #5

            @jenya7 said in Problem with a data from UDP:

            So data[0] is a char.

            It's just a collection of 8 bits. UDP makes no assumptions about the data it is transporting. You can cast it to proper type if you know what it is.

            (Z(:^

            J 1 Reply Last reply 8 Jul 2021, 10:54
            1
            • S sierdzio
              8 Jul 2021, 10:39

              @jenya7 said in Problem with a data from UDP:

              So data[0] is a char.

              It's just a collection of 8 bits. UDP makes no assumptions about the data it is transporting. You can cast it to proper type if you know what it is.

              J Offline
              J Offline
              jenya7
              wrote on 8 Jul 2021, 10:54 last edited by jenya7 7 Aug 2021, 11:23
              #6

              @sierdzio
              So every time I have to cast?

              if ( static_cast<uint8_t>(data[0]) == INTERFACE_ID_NONE || static_cast<uint8_t>(data[0]) > INTERFACE_ID_RS485)
                      return MSG_PARSE_ERROR_WRONG_INTFACE_ID;
                  else
                      sens_msg->interface_id = static_cast<uint8_t>(data[0]);
              

              It's not convenient at all. I have hundred bytes to parse. The first development environment I see that points char* to a network buffer.

              socket->readDatagram(  (uint8_t *) udp_buffer.data(),  udp_buffer.size(),  &sender,  &senderPort);
              

              error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')

              It should be (void *) in the function prototype.

              J 1 Reply Last reply 8 Jul 2021, 11:23
              0
              • J jenya7
                8 Jul 2021, 10:54

                @sierdzio
                So every time I have to cast?

                if ( static_cast<uint8_t>(data[0]) == INTERFACE_ID_NONE || static_cast<uint8_t>(data[0]) > INTERFACE_ID_RS485)
                        return MSG_PARSE_ERROR_WRONG_INTFACE_ID;
                    else
                        sens_msg->interface_id = static_cast<uint8_t>(data[0]);
                

                It's not convenient at all. I have hundred bytes to parse. The first development environment I see that points char* to a network buffer.

                socket->readDatagram(  (uint8_t *) udp_buffer.data(),  udp_buffer.size(),  &sender,  &senderPort);
                

                error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')

                It should be (void *) in the function prototype.

                J Offline
                J Offline
                JonB
                wrote on 8 Jul 2021, 11:23 last edited by JonB 7 Aug 2021, 11:26
                #7

                @jenya7
                QByteArray holds chars. uint8_t is unsigned char. If you compare them directly you are liable to get "unsigned/signed comparison" warnings. As you have seen.

                If you don't like having to explicitly do casting each time, you could, say, write your own utility function for "the i'th element of a QByteArray as unsigned char/uint_t", or the whole data as uint_t *.

                Separately, your parameter in ParseMessage(QByteArray data would be better declared as const QByteArray &data. But that won't change the casting issue.

                J 1 Reply Last reply 8 Jul 2021, 11:25
                0
                • J JonB
                  8 Jul 2021, 11:23

                  @jenya7
                  QByteArray holds chars. uint8_t is unsigned char. If you compare them directly you are liable to get "unsigned/signed comparison" warnings. As you have seen.

                  If you don't like having to explicitly do casting each time, you could, say, write your own utility function for "the i'th element of a QByteArray as unsigned char/uint_t", or the whole data as uint_t *.

                  Separately, your parameter in ParseMessage(QByteArray data would be better declared as const QByteArray &data. But that won't change the casting issue.

                  J Offline
                  J Offline
                  jenya7
                  wrote on 8 Jul 2021, 11:25 last edited by jenya7 7 Aug 2021, 11:27
                  #8

                  @JonB
                  socket->readDatagram( (uint8_t * ) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                  error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')

                  K 1 Reply Last reply 8 Jul 2021, 11:27
                  0
                  • J jenya7
                    8 Jul 2021, 11:25

                    @JonB
                    socket->readDatagram( (uint8_t * ) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                    error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')

                    K Offline
                    K Offline
                    KroMignon
                    wrote on 8 Jul 2021, 11:27 last edited by KroMignon 7 Aug 2021, 11:28
                    #9

                    @jenya7 said in Problem with a data from UDP:

                    socket->readDatagram( *(uint8_t ) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                    This should be: socket->readDatagram( (uint8_t *) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                    EDIT:
                    socket->readDatagram( udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                    It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                    J 1 Reply Last reply 8 Jul 2021, 11:28
                    1
                    • K KroMignon
                      8 Jul 2021, 11:27

                      @jenya7 said in Problem with a data from UDP:

                      socket->readDatagram( *(uint8_t ) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                      This should be: socket->readDatagram( (uint8_t *) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                      EDIT:
                      socket->readDatagram( udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                      J Offline
                      J Offline
                      jenya7
                      wrote on 8 Jul 2021, 11:28 last edited by
                      #10

                      @KroMignon said in Problem with a data from UDP:

                      @jenya7 said in Problem with a data from UDP:

                      socket->readDatagram( *(uint8_t ) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                      This should be: socket->readDatagram( (uint8_t *) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                      It is. The editor's problem

                      J K 2 Replies Last reply 8 Jul 2021, 11:29
                      0
                      • J jenya7
                        8 Jul 2021, 11:28

                        @KroMignon said in Problem with a data from UDP:

                        @jenya7 said in Problem with a data from UDP:

                        socket->readDatagram( *(uint8_t ) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                        This should be: socket->readDatagram( (uint8_t *) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                        It is. The editor's problem

                        J Offline
                        J Offline
                        JonB
                        wrote on 8 Jul 2021, 11:29 last edited by
                        #11

                        @jenya7 said in Problem with a data from UDP:

                        The editor's problem

                        What does this mean?! :)

                        1 Reply Last reply
                        0
                        • J jenya7
                          8 Jul 2021, 11:28

                          @KroMignon said in Problem with a data from UDP:

                          @jenya7 said in Problem with a data from UDP:

                          socket->readDatagram( *(uint8_t ) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                          This should be: socket->readDatagram( (uint8_t *) udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                          It is. The editor's problem

                          K Offline
                          K Offline
                          KroMignon
                          wrote on 8 Jul 2021, 11:30 last edited by
                          #12

                          @jenya7 said in Problem with a data from UDP:

                          It is. The editor's problem

                          Sorry, posted to quickly: remove the cast which is false / not required

                          It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                          1 Reply Last reply
                          0
                          • J Offline
                            J Offline
                            jenya7
                            wrote on 8 Jul 2021, 11:31 last edited by
                            #13

                            @KroMignon said in Problem with a data from UDP:

                            socket->readDatagram( udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                            This way I get array of chars I have to cast every byte.

                            socket->readDatagram((uint8_t *)udp_buffer.data(), udp_buffer.size(),  &sender, &senderPort);
                            

                            This way - error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')

                            J K 2 Replies Last reply 8 Jul 2021, 11:33
                            0
                            • S Offline
                              S Offline
                              sierdzio
                              Moderators
                              wrote on 8 Jul 2021, 11:32 last edited by
                              #14

                              You can use QDataStream to automatically convert all data to whatever format you require. To get a suitable device for it, use QBuffer.

                              (Z(:^

                              1 Reply Last reply
                              0
                              • J jenya7
                                8 Jul 2021, 11:31

                                @KroMignon said in Problem with a data from UDP:

                                socket->readDatagram( udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                                This way I get array of chars I have to cast every byte.

                                socket->readDatagram((uint8_t *)udp_buffer.data(), udp_buffer.size(),  &sender, &senderPort);
                                

                                This way - error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')

                                J Offline
                                J Offline
                                JonB
                                wrote on 8 Jul 2021, 11:33 last edited by
                                #15

                                @jenya7
                                You are misunderstanding C++. Going readDatagram((uint8_t *)udp_buffer.data() does not "make" the data actually be unsigned chars, it has no effect on "This way I get array of chars I have to cast every byte".

                                1 Reply Last reply
                                0
                                • J jenya7
                                  8 Jul 2021, 11:31

                                  @KroMignon said in Problem with a data from UDP:

                                  socket->readDatagram( udp_buffer.data(), udp_buffer.size(), &sender, &senderPort);

                                  This way I get array of chars I have to cast every byte.

                                  socket->readDatagram((uint8_t *)udp_buffer.data(), udp_buffer.size(),  &sender, &senderPort);
                                  

                                  This way - error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')

                                  K Offline
                                  K Offline
                                  KroMignon
                                  wrote on 8 Jul 2021, 11:34 last edited by KroMignon 7 Aug 2021, 11:34
                                  #16

                                  @jenya7 said in Problem with a data from UDP:

                                  his way - error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')

                                  What are you doing?
                                  socket is as instance of QUdpSocket and udp_buffer an instance of QByteArray or not?

                                  This must work, as I always do it!

                                      QByteArray datagram(socket->pendingDatagramSize(), 0);
                                      QHostAddress sender;
                                      quint16 senderPort;
                                  
                                      socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
                                  

                                  It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                  J 1 Reply Last reply 8 Jul 2021, 11:39
                                  1
                                  • K KroMignon
                                    8 Jul 2021, 11:34

                                    @jenya7 said in Problem with a data from UDP:

                                    his way - error: cannot initialize a parameter of type 'char *' with an rvalue of type 'uint8_t *' (aka 'unsigned char *')

                                    What are you doing?
                                    socket is as instance of QUdpSocket and udp_buffer an instance of QByteArray or not?

                                    This must work, as I always do it!

                                        QByteArray datagram(socket->pendingDatagramSize(), 0);
                                        QHostAddress sender;
                                        quint16 senderPort;
                                    
                                        socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
                                    
                                    J Offline
                                    J Offline
                                    jenya7
                                    wrote on 8 Jul 2021, 11:39 last edited by jenya7 7 Aug 2021, 11:40
                                    #17

                                    What are you doing?
                                    socket is as instance of QUdpSocket and udp_buffer an instance of QByteArray or not?

                                    Yes it is.
                                    But taking char by char form datagram.data()
                                    I have to cast - uint8_t b0 = static_cast<uint8_t>(datagram[0]);

                                    K J 2 Replies Last reply 8 Jul 2021, 11:40
                                    0
                                    • J jenya7
                                      8 Jul 2021, 11:39

                                      What are you doing?
                                      socket is as instance of QUdpSocket and udp_buffer an instance of QByteArray or not?

                                      Yes it is.
                                      But taking char by char form datagram.data()
                                      I have to cast - uint8_t b0 = static_cast<uint8_t>(datagram[0]);

                                      K Offline
                                      K Offline
                                      KroMignon
                                      wrote on 8 Jul 2021, 11:40 last edited by KroMignon 7 Aug 2021, 11:43
                                      #18

                                      @jenya7 said in Problem with a data from UDP:

                                      Yes it is.
                                      But taking char by char form datagram.data()
                                      I have to cast - byte b0 = static_cast<uint8_t>(datagram[0]);

                                      No:

                                      for(const auto b : datagram)
                                      {
                                         qDebug() << "Byte value:" << quint8(b);
                                      }
                                      

                                      EDIT
                                      or

                                      uint8_t* myPoint = static_cast<uint8_t*>(datagram.data());
                                      
                                      

                                      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                      J 1 Reply Last reply 8 Jul 2021, 12:00
                                      0
                                      • J jenya7
                                        8 Jul 2021, 11:39

                                        What are you doing?
                                        socket is as instance of QUdpSocket and udp_buffer an instance of QByteArray or not?

                                        Yes it is.
                                        But taking char by char form datagram.data()
                                        I have to cast - uint8_t b0 = static_cast<uint8_t>(datagram[0]);

                                        J Offline
                                        J Offline
                                        JonB
                                        wrote on 8 Jul 2021, 11:41 last edited by JonB 7 Aug 2021, 11:43
                                        #19

                                        @jenya7
                                        I will contribute one more time. I already told you what to do if you want to reduce repeated casting:

                                        If you don't like having to explicitly do casting each time, you could, say, write your own utility function for "the i'th element of a QByteArray as unsigned char/uint_t", or the whole data as uint_t *.

                                        Same applies anywhere else.

                                        For the record: I believe there have been discussions over the years about how some people would have preferred QByteArray to hold unsigned chars instead of chars. It stays with chars due (at least partly) to it's (slightly weird) determination to end the data with \0 and allow it to interchange fairly free with QString. This is not convenient for your case, but it is what it is, so you're going to have to work with it.

                                        J 1 Reply Last reply 8 Jul 2021, 11:44
                                        0
                                        • J JonB
                                          8 Jul 2021, 11:41

                                          @jenya7
                                          I will contribute one more time. I already told you what to do if you want to reduce repeated casting:

                                          If you don't like having to explicitly do casting each time, you could, say, write your own utility function for "the i'th element of a QByteArray as unsigned char/uint_t", or the whole data as uint_t *.

                                          Same applies anywhere else.

                                          For the record: I believe there have been discussions over the years about how some people would have preferred QByteArray to hold unsigned chars instead of chars. It stays with chars due (at least partly) to it's (slightly weird) determination to end the data with \0 and allow it to interchange fairly free with QString. This is not convenient for your case, but it is what it is, so you're going to have to work with it.

                                          J Offline
                                          J Offline
                                          jenya7
                                          wrote on 8 Jul 2021, 11:44 last edited by
                                          #20

                                          @JonB said in Problem with a data from UDP:

                                          @jenya7
                                          I will contribute one more time. I already told you what to do if you want to reduce repeated casting:

                                          If you don't like having to explicitly do casting each time, you could, say, write your own utility function for "the i'th element of a QByteArray as unsigned char/uint_t", or the whole data as uint_t *.

                                          Same applies anywhere else.

                                          To cast each element in a loop? It makes even worse, waste of run time.

                                          K J 2 Replies Last reply 8 Jul 2021, 11:44
                                          0

                                          8/28

                                          8 Jul 2021, 11:25

                                          20 unread
                                          • Login

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