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. QNetworkDatagram.data() appends null char
QtWS25 Last Chance

QNetworkDatagram.data() appends null char

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 5 Posters 1.0k 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.
  • M Offline
    M Offline
    mzimmers
    wrote on 19 May 2020, 14:23 last edited by
    #1

    Hi all -

    My app reads a UDP socket and processes the message. I need to test for a complete message, as determined by the presence of a end tag.

    The QNetworkDatagram.data() call appends a null character to the QByteArray that is causing the endsWith() function to fail.

    QByteArray endTag("</XML>\n\0");
    QByteArray right = m_datagramIn.data().right(8);
    qDebug() << endTag << endl << right << endl << m_datagramIn.data();
    if (m_datagramIn.data().endsWith(endTag))
    {
    ...
    

    Note that my effort to append a null character to my endTag fails; at least as shown by the qDebug() call. Also, the test fails.

    I cannot reproduce this problem using only QByteArrays; it has something to do with the data() call.

    I could easily hack a solution, but I'm wondering if anyone knows why this is happening, and whether it might be a bug.

    5.14.2, Windows 10.

    Thanks...

    J 1 Reply Last reply 19 May 2020, 14:30
    0
    • M mzimmers
      19 May 2020, 14:23

      Hi all -

      My app reads a UDP socket and processes the message. I need to test for a complete message, as determined by the presence of a end tag.

      The QNetworkDatagram.data() call appends a null character to the QByteArray that is causing the endsWith() function to fail.

      QByteArray endTag("</XML>\n\0");
      QByteArray right = m_datagramIn.data().right(8);
      qDebug() << endTag << endl << right << endl << m_datagramIn.data();
      if (m_datagramIn.data().endsWith(endTag))
      {
      ...
      

      Note that my effort to append a null character to my endTag fails; at least as shown by the qDebug() call. Also, the test fails.

      I cannot reproduce this problem using only QByteArrays; it has something to do with the data() call.

      I could easily hack a solution, but I'm wondering if anyone knows why this is happening, and whether it might be a bug.

      5.14.2, Windows 10.

      Thanks...

      J Offline
      J Offline
      jsulm
      Lifetime Qt Champion
      wrote on 19 May 2020, 14:30 last edited by
      #2

      @mzimmers How do you send the datagram? I don't think data() appends anything.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      M 1 Reply Last reply 19 May 2020, 15:33
      1
      • J jsulm
        19 May 2020, 14:30

        @mzimmers How do you send the datagram? I don't think data() appends anything.

        M Offline
        M Offline
        mzimmers
        wrote on 19 May 2020, 15:33 last edited by
        #3

        @jsulm this is an incoming datagram, processed by a slot that picks up readyRead().

        A 1 Reply Last reply 19 May 2020, 16:05
        0
        • M mzimmers
          19 May 2020, 15:33

          @jsulm this is an incoming datagram, processed by a slot that picks up readyRead().

          A Offline
          A Offline
          aha_1980
          Lifetime Qt Champion
          wrote on 19 May 2020, 16:05 last edited by
          #4

          @mzimmers

          first you should check the datagram in wireshark.

          I also doubt the null byte is random.

          Regards

          Qt has to stay free or it will die.

          M 1 Reply Last reply 19 May 2020, 16:13
          0
          • A aha_1980
            19 May 2020, 16:05

            @mzimmers

            first you should check the datagram in wireshark.

            I also doubt the null byte is random.

            Regards

            M Offline
            M Offline
            mzimmers
            wrote on 19 May 2020, 16:13 last edited by
            #5

            @aha_1980 the null char is indeed part of the data. But I wasn't expecting it to be added to the QByteArray (my error I guess).

            So, given that this is occurring within a slot, I'm trying to minimize the amount of data copying I'm doing. I'm assuming I can't edit the datagram itself, can I? So, how do I construct my endTag so that my compare will return true? It seems weird that my code example doesn't keep the null.

            A 1 Reply Last reply 19 May 2020, 16:15
            0
            • M mzimmers
              19 May 2020, 16:13

              @aha_1980 the null char is indeed part of the data. But I wasn't expecting it to be added to the QByteArray (my error I guess).

              So, given that this is occurring within a slot, I'm trying to minimize the amount of data copying I'm doing. I'm assuming I can't edit the datagram itself, can I? So, how do I construct my endTag so that my compare will return true? It seems weird that my code example doesn't keep the null.

              A Offline
              A Offline
              aha_1980
              Lifetime Qt Champion
              wrote on 19 May 2020, 16:15 last edited by
              #6

              @mzimmers how do you know it doesn't keep the null byte?

              Try qDebug() << endTag.toHex().

              Regards

              Qt has to stay free or it will die.

              M 1 Reply Last reply 19 May 2020, 16:20
              0
              • A aha_1980
                19 May 2020, 16:15

                @mzimmers how do you know it doesn't keep the null byte?

                Try qDebug() << endTag.toHex().

                Regards

                M Offline
                M Offline
                mzimmers
                wrote on 19 May 2020, 16:20 last edited by
                #7

                @aha_1980 well for one thing the endsWith() returns false. Here's the hex for all three arrays:

                 qDebug() << endTag.toHex() << endl << right.toHex() << endl << m_datagramIn.data().toHex();
                
                
                "3c2f584d4c3e" 
                "3c2f584d4c3e0a00" 
                "3c584d4c3e3c5061636b6574547970653e526573706f6e73653c2f5061636b6574547970653e0a3c50726f647563744e616d653e45544320537065616b65723c2f50726f647563744e616d653e0a3c53657269616c4e756d3e3435373030303030323c2f53657269616c4e756d3e0a3c4d6163416464723e30303a32303a66373a30343a32613a37643c2f4d6163416464723e0a3c4950416464723e31302e31302e302e3135343c2f4950416464723e0a3c4465764e616d653e494320456e61626c656420506167696e6720416d703c2f4465764e616d653e0a3c444843503e456e61626c65643c2f444843503e0a3c2f584d4c3e0a00"
                

                Strange, no?

                A 1 Reply Last reply 19 May 2020, 16:32
                0
                • M mzimmers
                  19 May 2020, 16:20

                  @aha_1980 well for one thing the endsWith() returns false. Here's the hex for all three arrays:

                   qDebug() << endTag.toHex() << endl << right.toHex() << endl << m_datagramIn.data().toHex();
                  
                  
                  "3c2f584d4c3e" 
                  "3c2f584d4c3e0a00" 
                  "3c584d4c3e3c5061636b6574547970653e526573706f6e73653c2f5061636b6574547970653e0a3c50726f647563744e616d653e45544320537065616b65723c2f50726f647563744e616d653e0a3c53657269616c4e756d3e3435373030303030323c2f53657269616c4e756d3e0a3c4d6163416464723e30303a32303a66373a30343a32613a37643c2f4d6163416464723e0a3c4950416464723e31302e31302e302e3135343c2f4950416464723e0a3c4465764e616d653e494320456e61626c656420506167696e6720416d703c2f4465764e616d653e0a3c444843503e456e61626c65643c2f444843503e0a3c2f584d4c3e0a00"
                  

                  Strange, no?

                  A Offline
                  A Offline
                  aha_1980
                  Lifetime Qt Champion
                  wrote on 19 May 2020, 16:32 last edited by
                  #8

                  @mzimmers ah, got it. you cannot embed \0 in a C-string... QByteArray is unguilty.

                  try endTag.append('\0'); instead.

                  Regards

                  Qt has to stay free or it will die.

                  M 1 Reply Last reply 19 May 2020, 16:47
                  2
                  • A aha_1980
                    19 May 2020, 16:32

                    @mzimmers ah, got it. you cannot embed \0 in a C-string... QByteArray is unguilty.

                    try endTag.append('\0'); instead.

                    Regards

                    M Offline
                    M Offline
                    mzimmers
                    wrote on 19 May 2020, 16:47 last edited by
                    #9

                    @aha_1980 very good...that works:

                                QByteArray endTag("</XML>");
                                endTag.append('\n');
                                endTag.append('\0');
                                if (m_datagramIn.data().endsWith(endTag))
                                {
                    

                    So, is there a preferred way for me to build my endTag? Ideally it would be a const, given that this is a slot (and therefore something of an ISR), and performance is important.

                    Thanks...

                    A 1 Reply Last reply 19 May 2020, 16:57
                    0
                    • M mzimmers
                      19 May 2020, 16:47

                      @aha_1980 very good...that works:

                                  QByteArray endTag("</XML>");
                                  endTag.append('\n');
                                  endTag.append('\0');
                                  if (m_datagramIn.data().endsWith(endTag))
                                  {
                      

                      So, is there a preferred way for me to build my endTag? Ideally it would be a const, given that this is a slot (and therefore something of an ISR), and performance is important.

                      Thanks...

                      A Offline
                      A Offline
                      aha_1980
                      Lifetime Qt Champion
                      wrote on 19 May 2020, 16:57 last edited by
                      #10

                      @mzimmers if you can use C++11, raw string literals come to mind. otherwise you could make the variable a membr and keep it for multiple invocations.

                      Qt has to stay free or it will die.

                      M 1 Reply Last reply 19 May 2020, 17:05
                      1
                      • A aha_1980
                        19 May 2020, 16:57

                        @mzimmers if you can use C++11, raw string literals come to mind. otherwise you could make the variable a membr and keep it for multiple invocations.

                        M Offline
                        M Offline
                        mzimmers
                        wrote on 19 May 2020, 17:05 last edited by
                        #11

                        @aha_1980 how would using raw string literals allow me to embed a null char (or newline)?

                        JonBJ 1 Reply Last reply 19 May 2020, 17:29
                        0
                        • B Offline
                          B Offline
                          Bonnie
                          wrote on 19 May 2020, 17:25 last edited by
                          #12

                          A little inflexible, but you can set byte size manually

                          const QByteArray endTag("</XML>\n\0", 8);
                          
                          1 Reply Last reply
                          2
                          • M mzimmers
                            19 May 2020, 17:05

                            @aha_1980 how would using raw string literals allow me to embed a null char (or newline)?

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on 19 May 2020, 17:29 last edited by JonB
                            #13

                            @mzimmers
                            \n has never been a problem. You are going to have problems trying to embed any extra \0 inside a " string. You could spell it out via { '<', '/', ... '>', '\0' } but you may not like readability. Do you need the \0 to actually be there, could you deal with that in code instead?

                            If you want to be naughty/impressive(?): QByteArray stores an extra \0 at the end anyway, always! It's not included in count/size(), but it is there, and documented (https://doc.qt.io/qt-5/qbytearray.html#details). So you could use the one which is there. Personally not sure I would, but up to you... :)

                            1 Reply Last reply
                            0
                            • M Offline
                              M Offline
                              mzimmers
                              wrote on 19 May 2020, 17:32 last edited by
                              #14

                              Bonnie's solution is perfect. For my education, though...why doesn't it work without the length specifier, but works with it? I'm working with a QByteArray, so I don't see how C-string rules apply, unless the argument (the stuff in quotes) is being interpreted as a C-string...

                              JonBJ 1 Reply Last reply 19 May 2020, 17:36
                              0
                              • M mzimmers
                                19 May 2020, 17:32

                                Bonnie's solution is perfect. For my education, though...why doesn't it work without the length specifier, but works with it? I'm working with a QByteArray, so I don't see how C-string rules apply, unless the argument (the stuff in quotes) is being interpreted as a C-string...

                                JonBJ Offline
                                JonBJ Offline
                                JonB
                                wrote on 19 May 2020, 17:36 last edited by JonB
                                #15

                                @mzimmers
                                Yes, the parameter in QByteArray endTag("</XML>\n\0") is what you call a C string. The fact that is being passed to, say, a QByteArray constructor does not alter this fact. When QByteArray copies the characters from there it stops at the first \0. When @Bonnie specifies the length explicitly in his constructor call it copies the 8 characters he specifies.

                                The problem is that you have to maintain this for every literal token you have, and one day you'll get the byte count out of sync with the string next to it. Which is why I would do your whole thing in code, I really don't think you're doing yourself any favours by playing around with literals here when it's not necessary. Why don't you reconsider?

                                1 Reply Last reply
                                2
                                • M Offline
                                  M Offline
                                  mzimmers
                                  wrote on 19 May 2020, 17:38 last edited by
                                  #16

                                  Thanks for the help...it's been educational.

                                  Now, if I could just get someone to help me in the installer forum (heh)...

                                  1 Reply Last reply
                                  0

                                  1/16

                                  19 May 2020, 14:23

                                  • Login

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