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. Still having trouble deserializing binary data from another UDP source (non-qt)
Forum Update on Monday, May 27th 2025

Still having trouble deserializing binary data from another UDP source (non-qt)

Scheduled Pinned Locked Moved Unsolved General and Desktop
29 Posts 4 Posters 2.7k 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.
  • R RobbieP
    10 May 2022, 13:20

    In the first screenshot, I'm concerned about the null characters at position 1,2,3 after the packet size. The packet size is supposed to be 8. What are those three null characters after the 8 before the first NAME value of TimeElapsed.

    J Offline
    J Offline
    JonB
    wrote on 10 May 2022, 13:22 last edited by
    #4

    @RobbieP said in Still having trouble deserializing binary data from another UDP source (non-qt):

    What are those three null characters after the 8 before the first NAME value of TimeElapsed.

    4-byte/32-bit int, LSB-first, little-endian.

    1 Reply Last reply
    3
    • R RobbieP
      10 May 2022, 13:20

      In the first screenshot, I'm concerned about the null characters at position 1,2,3 after the packet size. The packet size is supposed to be 8. What are those three null characters after the 8 before the first NAME value of TimeElapsed.

      J Offline
      J Offline
      J.Hilk
      Moderators
      wrote on 10 May 2022, 13:24 last edited by
      #5

      @RobbieP seems like typical Data Structure alignment issues.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      0
      • R RobbieP
        10 May 2022, 13:11

        HI all. I previously had some great help from @KroMignon on this topic, but anyone can feel free to jump in.

        I'm writing a program to receive and log data from a data source in our lab. The data is structured as such:

        #define SP_PACKET_SIZE 200
        #define NAME_SIZE 64
            struct fennecPacketStruct
            {
                int Size;                               ///< Number of items in the data packet
                char Name[SP_PACKET_SIZE][NAME_SIZE];   ///< Data labels
                double Value[SP_PACKET_SIZE];           ///< Data packet values
            };
        

        and it's sent via UDP in binary: (char *)fennecPacket

        The sample code using QT to serialize and deserialize the packet works great. But it's having trouble deserializing the packet from the external source...so I'm wondering what changes I need to make to the deserializer to possibly fix it? Here's some screenshots showing the code and the Raw Packet data as well as the result of the initial deserialization.
        Screenshot_2022-05-10_09-01-29_1920x1080.jpg

        ![0_1652188242645_Screenshot_2022-05-10_09-01-48_1920x1080.jpg](Uploading 100%)

        void MainWindow::readPendingDatagrams()
        {
            fennecPacketStruct inPacket;
            while (udpSocket->hasPendingDatagrams()) {
                QHostAddress ThisHost;
                quint16 ThisPort;
                QByteArray ThisPacket;
                ThisPacket.resize(udpSocket->pendingDatagramSize());
                udpSocket->readDatagram(ThisPacket.data(), ThisPacket.size(), &ThisHost, &ThisPort);
                QDataStream deserialize(ThisPacket);
        
                deserialize >> inPacket.Size;
                if(inPacket.Size > 0)
                {
                    deserialize.readRawData(reinterpret_cast<char *>(inPacket.Name), NAME_SIZE * inPacket.Size);
                    deserialize.readRawData(reinterpret_cast<char *>(inPacket.Value), sizeof(double) * inPacket.Size);
                }
        
        J Offline
        J Offline
        JonB
        wrote on 10 May 2022, 13:25 last edited by JonB 5 Oct 2022, 13:27
        #6

        @RobbieP

        • What exactly is going wrong with your code (if anything)?

        • Does your code work right when inPacket.Size == 1? And only go wrong when larger than that? Or always? Or what?

        • You thanked @KroMignon for his code in https://forum.qt.io/topic/135363/trouble-with-serializing-and-deserializing-structs/6, saying it was working for you. You seem to be using the same code. What has changed since then?

        R 2 Replies Last reply 10 May 2022, 13:30
        0
        • J JonB
          10 May 2022, 13:25

          @RobbieP

          • What exactly is going wrong with your code (if anything)?

          • Does your code work right when inPacket.Size == 1? And only go wrong when larger than that? Or always? Or what?

          • You thanked @KroMignon for his code in https://forum.qt.io/topic/135363/trouble-with-serializing-and-deserializing-structs/6, saying it was working for you. You seem to be using the same code. What has changed since then?

          R Offline
          R Offline
          RobbieP
          wrote on 10 May 2022, 13:30 last edited by
          #7

          @JonB the code hasn't changed since that original post...what has changed is that in that sample code, I was serializing the data in qt and deserializing it in qt...same program actually, just sent over localhost to itself. This error has occurred while trying to process the data from another program, which is how it was initially supposed to work in the first place. The error I get is a seg fault on the second deserialize.readRawData

          I'll try the packet size of 1 and see what happens.

          J 1 Reply Last reply 10 May 2022, 14:00
          0
          • J JonB
            10 May 2022, 13:25

            @RobbieP

            • What exactly is going wrong with your code (if anything)?

            • Does your code work right when inPacket.Size == 1? And only go wrong when larger than that? Or always? Or what?

            • You thanked @KroMignon for his code in https://forum.qt.io/topic/135363/trouble-with-serializing-and-deserializing-structs/6, saying it was working for you. You seem to be using the same code. What has changed since then?

            R Offline
            R Offline
            RobbieP
            wrote on 10 May 2022, 13:32 last edited by
            #8

            @JonB do I need to change my deserialize to QDataStream::LittleEndian? It's currently BigEndian

            K J 2 Replies Last reply 10 May 2022, 13:41
            0
            • R RobbieP
              10 May 2022, 13:32

              @JonB do I need to change my deserialize to QDataStream::LittleEndian? It's currently BigEndian

              K Offline
              K Offline
              KroMignon
              wrote on 10 May 2022, 13:41 last edited by KroMignon 5 Oct 2022, 13:45
              #9

              @RobbieP said in Still having trouble deserializing binary data from another UDP source (non-qt):

              do I need to change my deserialize to QDataStream::LittleEndian? It's currently BigEndian

              How should we know this? Is your remote application using big or little endian byte order?

              [EDIT]: you could do a kind of "sanity check" with:

              deserialize >> inPacket.Size;
              qDebug() << "Readed size:" <<  inPacket.Size;
              int expectedSize = (ThisPacket.length()  - sizeof(int))/(NAME_SIZE +sizeof(double));
              qDebug() << "Expected size:" <<  expectedSize;
              
              

              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
              • R RobbieP
                10 May 2022, 13:32

                @JonB do I need to change my deserialize to QDataStream::LittleEndian? It's currently BigEndian

                J Offline
                J Offline
                JonB
                wrote on 10 May 2022, 13:42 last edited by JonB 5 Oct 2022, 13:44
                #10

                @RobbieP
                Hmm. In principle it does not matter so long as both sender & receiver are using same-endianness.

                Having said that, bytes you show of 8, 0, 0, 0 look little-endian to me, from the sender's side??

                In any case

                deserialize >> inPacket.Size;
                qDebug() << inPacket.Size;
                

                Put qDebug()s in while you are developing deserialization! Either this will print 8, which is good, or it will print millions & billions, in which case NAME_SIZE * inPacket.Size etc. will be really bad (and cause seg faults)! :)

                Also int QDataStream::readRawData(char *s, int len) "returns the number of bytes read", which you should be printing out/checking....

                R 1 Reply Last reply 10 May 2022, 13:45
                0
                • J JonB
                  10 May 2022, 13:42

                  @RobbieP
                  Hmm. In principle it does not matter so long as both sender & receiver are using same-endianness.

                  Having said that, bytes you show of 8, 0, 0, 0 look little-endian to me, from the sender's side??

                  In any case

                  deserialize >> inPacket.Size;
                  qDebug() << inPacket.Size;
                  

                  Put qDebug()s in while you are developing deserialization! Either this will print 8, which is good, or it will print millions & billions, in which case NAME_SIZE * inPacket.Size etc. will be really bad (and cause seg faults)! :)

                  Also int QDataStream::readRawData(char *s, int len) "returns the number of bytes read", which you should be printing out/checking....

                  R Offline
                  R Offline
                  RobbieP
                  wrote on 10 May 2022, 13:45 last edited by
                  #11

                  @JonB the inPacket.Size is being read as 134217728

                  J 1 Reply Last reply 10 May 2022, 13:47
                  0
                  • R RobbieP
                    10 May 2022, 13:45

                    @JonB the inPacket.Size is being read as 134217728

                    J Offline
                    J Offline
                    JonB
                    wrote on 10 May 2022, 13:47 last edited by JonB 5 Oct 2022, 13:50
                    #12

                    @RobbieP said in Still having trouble deserializing binary data from another UDP source (non-qt):

                    @JonB the inPacket.Size is being read as 134217728

                    :) As suspected. My "millions & billions"! Wrong endianness, sender & receiver are reversed, they must agree....

                    134217728 == 0x08000000! Your little-endian-saved number is being read as big-endian....

                    R 1 Reply Last reply 10 May 2022, 13:52
                    1
                    • J JonB
                      10 May 2022, 13:47

                      @RobbieP said in Still having trouble deserializing binary data from another UDP source (non-qt):

                      @JonB the inPacket.Size is being read as 134217728

                      :) As suspected. My "millions & billions"! Wrong endianness, sender & receiver are reversed, they must agree....

                      134217728 == 0x08000000! Your little-endian-saved number is being read as big-endian....

                      R Offline
                      R Offline
                      RobbieP
                      wrote on 10 May 2022, 13:52 last edited by
                      #13

                      @JonB oh man...how do I fix that? Do I just set the endianness of the QDataStream?

                      1 Reply Last reply
                      0
                      • R RobbieP
                        10 May 2022, 13:30

                        @JonB the code hasn't changed since that original post...what has changed is that in that sample code, I was serializing the data in qt and deserializing it in qt...same program actually, just sent over localhost to itself. This error has occurred while trying to process the data from another program, which is how it was initially supposed to work in the first place. The error I get is a seg fault on the second deserialize.readRawData

                        I'll try the packet size of 1 and see what happens.

                        J Offline
                        J Offline
                        JonB
                        wrote on 10 May 2022, 14:00 last edited by JonB 5 Oct 2022, 14:01
                        #14

                        @RobbieP said in Still having trouble deserializing binary data from another UDP source (non-qt):

                        same program actually, just sent over localhost to itself. This error has occurred while trying to process the data from another program

                        When sending over localhost to self the endianness of the machine does not change, so defaults should be fine. Either this test was from another, different-architecture machine, or if it is same machine you must go and look at the sender's Qt code. Your receiver must be set to agree with that. It looks like "the data from another program" was explicitly set to little-endian, you will need that if it's not your default.

                        Meanwhile your receiver code should have a look at QDataStream::ByteOrder QDataStream::byteOrder() const

                        Returns the current byte order setting -- either BigEndian or LittleEndian.

                        Oh, I see void QDataStream::setByteOrder(QDataStream::ByteOrder bo)

                        The default setting is big endian. We recommend leaving this setting unless you have special requirements.

                        I think you said that's what your receiver end has. So it looks like the sender side explicitly changed that?

                        1 Reply Last reply
                        0
                        • R Offline
                          R Offline
                          RobbieP
                          wrote on 10 May 2022, 14:07 last edited by
                          #15

                          The Sender isn't written in QT...it's just using regular socket sending. I'm not sure it's explicitly setting the endianness but I'll look.

                          When I set

                               deserialize.setByteOrder(QDataStream::LittleEndian);
                          

                          I get a size of 8, which is correct. And I get all the name values correctly. But now it's not properly deserializing the doubles in the value section. So close i can taste it though. I really appreciate the help. I'm starting to wrap my mind around this stuff now, but doing it in QT is still pretty new to me.

                          J 1 Reply Last reply 10 May 2022, 14:14
                          0
                          • R Offline
                            R Offline
                            RobbieP
                            wrote on 10 May 2022, 14:12 last edited by
                            #16

                            The doubles are all coming in as 0 or very close to 0.

                            1 Reply Last reply
                            0
                            • R RobbieP
                              10 May 2022, 14:07

                              The Sender isn't written in QT...it's just using regular socket sending. I'm not sure it's explicitly setting the endianness but I'll look.

                              When I set

                                   deserialize.setByteOrder(QDataStream::LittleEndian);
                              

                              I get a size of 8, which is correct. And I get all the name values correctly. But now it's not properly deserializing the doubles in the value section. So close i can taste it though. I really appreciate the help. I'm starting to wrap my mind around this stuff now, but doing it in QT is still pretty new to me.

                              J Offline
                              J Offline
                              JonB
                              wrote on 10 May 2022, 14:14 last edited by JonB 5 Oct 2022, 14:17
                              #17

                              @RobbieP said in Still having trouble deserializing binary data from another UDP source (non-qt):

                              The Sender isn't written in QT...it's just using regular socket sending.

                              Whaaattt!!?? Why did you not say this from the outset? You cannot/must not/should not attempt to use QDataStream for anything other than QDataStream<->QDataStream exchange. It puts in its own meta-data.

                              Back to the drawing board. Remove QDataStream. Do whatever coding you need for whatever the other end sends in whatever format it uses....

                              If you insist on using QDataStream, just using raw byte stuff, I don't much see the point but it's up to you. Certainly then deserialize >> inPacket.Size; is pretty dodgy.

                              1 Reply Last reply
                              1
                              • R Offline
                                R Offline
                                RobbieP
                                wrote on 10 May 2022, 14:19 last edited by
                                #18

                                Sorry I thought I mentioned it...I looked back up and it seems I just said "sent in UDP" I meant to say it's using a custom udp sender and the packet is just sent as (char*)packet without going through a serializer. So...a little background information. The program I'm replacing with a QT app was multicast...it was destroying our network, but I don't have the source code for it. Only the source code for the sender. I've modified the sender (which is a plugin for the X-Plane flight simulator, so I can't use QT) to only do unicast. And I've rewritten the receiver in QT. So to be honest...I've never deserialized without qt. Can I just read the data in directly to a struct and assume it would work if the byteorder is the same on both ends?

                                J 1 Reply Last reply 10 May 2022, 14:26
                                0
                                • R RobbieP
                                  10 May 2022, 14:19

                                  Sorry I thought I mentioned it...I looked back up and it seems I just said "sent in UDP" I meant to say it's using a custom udp sender and the packet is just sent as (char*)packet without going through a serializer. So...a little background information. The program I'm replacing with a QT app was multicast...it was destroying our network, but I don't have the source code for it. Only the source code for the sender. I've modified the sender (which is a plugin for the X-Plane flight simulator, so I can't use QT) to only do unicast. And I've rewritten the receiver in QT. So to be honest...I've never deserialized without qt. Can I just read the data in directly to a struct and assume it would work if the byteorder is the same on both ends?

                                  J Offline
                                  J Offline
                                  JonB
                                  wrote on 10 May 2022, 14:26 last edited by JonB 5 Oct 2022, 14:29
                                  #19

                                  @RobbieP said in Still having trouble deserializing binary data from another UDP source (non-qt):

                                  Can I just read the data in directly to a struct and assume it would work if the byteorder is the same on both ends?

                                  Nope, because of possible packing/data alignment issues....

                                  At the end of the day you must know, somehow, how the data was sent/formatted. You will also need to know if it sends things like ints, and what endianness it does that in. As in: without that you can't read the data back sensibly.

                                  I don't know whether others would say you can still use QDataStream::readRawData() safely, or if you did whether you are then getting much benefit out of QDataStream anyway.

                                  If it were me I would just write code to read chunks of bytes as per whatever the sender's format is. Then I know where I am for sure. Qt/C++/C have functions to transform between endian integers without having to use QDataStream. Suggest do not read into a struct directly, read into each member separately as per what you were doing. Then alignment at receiving size won't be an issue. But without looking at sending code's side, can't be sure whether that might have padding/alignment. If we assume sender itself did not e.g. send any structs as a whole you may be good.

                                  Off you go, and do lots of testing on sender's packets!

                                  I've never deserialized without qt

                                  OK, if you really want to try sticking with it. Just tell your receiver QDataStream to be little-endian. See whether that sorts the current issue to your satisfaction. If so, try lots of others. If they all work, you can stick with QDataStream I guess....

                                  R 2 Replies Last reply 10 May 2022, 14:58
                                  1
                                  • J JonB
                                    10 May 2022, 14:26

                                    @RobbieP said in Still having trouble deserializing binary data from another UDP source (non-qt):

                                    Can I just read the data in directly to a struct and assume it would work if the byteorder is the same on both ends?

                                    Nope, because of possible packing/data alignment issues....

                                    At the end of the day you must know, somehow, how the data was sent/formatted. You will also need to know if it sends things like ints, and what endianness it does that in. As in: without that you can't read the data back sensibly.

                                    I don't know whether others would say you can still use QDataStream::readRawData() safely, or if you did whether you are then getting much benefit out of QDataStream anyway.

                                    If it were me I would just write code to read chunks of bytes as per whatever the sender's format is. Then I know where I am for sure. Qt/C++/C have functions to transform between endian integers without having to use QDataStream. Suggest do not read into a struct directly, read into each member separately as per what you were doing. Then alignment at receiving size won't be an issue. But without looking at sending code's side, can't be sure whether that might have padding/alignment. If we assume sender itself did not e.g. send any structs as a whole you may be good.

                                    Off you go, and do lots of testing on sender's packets!

                                    I've never deserialized without qt

                                    OK, if you really want to try sticking with it. Just tell your receiver QDataStream to be little-endian. See whether that sorts the current issue to your satisfaction. If so, try lots of others. If they all work, you can stick with QDataStream I guess....

                                    R Offline
                                    R Offline
                                    RobbieP
                                    wrote on 10 May 2022, 14:58 last edited by
                                    #20

                                    @JonB I'm getting the correct names and the size...the doubles are off though...does the second readRawData start where the previous readRawData left off? calling readRawData back to back like that doesn't reset the position does it?

                                    1 Reply Last reply
                                    0
                                    • J JonB
                                      10 May 2022, 14:26

                                      @RobbieP said in Still having trouble deserializing binary data from another UDP source (non-qt):

                                      Can I just read the data in directly to a struct and assume it would work if the byteorder is the same on both ends?

                                      Nope, because of possible packing/data alignment issues....

                                      At the end of the day you must know, somehow, how the data was sent/formatted. You will also need to know if it sends things like ints, and what endianness it does that in. As in: without that you can't read the data back sensibly.

                                      I don't know whether others would say you can still use QDataStream::readRawData() safely, or if you did whether you are then getting much benefit out of QDataStream anyway.

                                      If it were me I would just write code to read chunks of bytes as per whatever the sender's format is. Then I know where I am for sure. Qt/C++/C have functions to transform between endian integers without having to use QDataStream. Suggest do not read into a struct directly, read into each member separately as per what you were doing. Then alignment at receiving size won't be an issue. But without looking at sending code's side, can't be sure whether that might have padding/alignment. If we assume sender itself did not e.g. send any structs as a whole you may be good.

                                      Off you go, and do lots of testing on sender's packets!

                                      I've never deserialized without qt

                                      OK, if you really want to try sticking with it. Just tell your receiver QDataStream to be little-endian. See whether that sorts the current issue to your satisfaction. If so, try lots of others. If they all work, you can stick with QDataStream I guess....

                                      R Offline
                                      R Offline
                                      RobbieP
                                      wrote on 10 May 2022, 15:02 last edited by
                                      #21

                                      @JonB I ask because I'm curious if it's possible the second readRawData isn't tryign to convert the 200 64 character names into doubles.

                                      J 1 Reply Last reply 10 May 2022, 15:11
                                      0
                                      • R RobbieP
                                        10 May 2022, 15:02

                                        @JonB I ask because I'm curious if it's possible the second readRawData isn't tryign to convert the 200 64 character names into doubles.

                                        J Offline
                                        J Offline
                                        JonB
                                        wrote on 10 May 2022, 15:11 last edited by JonB 5 Oct 2022, 15:12
                                        #22

                                        @RobbieP
                                        No, your readRawData()s run sequentially, carrying on from where they got to.

                                        Possibilities:

                                        • Sender does have some pad between end of Name and start of Value.
                                        • Sender saves doubles as something other than write(&double, sizeof(double)).
                                        • Sender is different architecture which represents doubles differently. Though I kind of doubt this, I believe there is some standard for how doubles are represented which is cross-architecture.
                                        • QDataStream encodes double with some extra information. Though I doubt this.

                                        the doubles are off though

                                        How "off" is "off"? Slightly wrong, or way out there?

                                        Suggestions:

                                        • You really should put those checks in on return result of QDataStream::readRawData().
                                        • Can you get the sender to send just with inPacket.Size = 1 while you get it sorted out?
                                        • Try it with plain read()s and no QDataStream. Though if that does not work you're a bit stuck.
                                        • Do you have the source code of the sender's write()ing code to examine?
                                        R 1 Reply Last reply 10 May 2022, 15:30
                                        0
                                        • J JonB
                                          10 May 2022, 15:11

                                          @RobbieP
                                          No, your readRawData()s run sequentially, carrying on from where they got to.

                                          Possibilities:

                                          • Sender does have some pad between end of Name and start of Value.
                                          • Sender saves doubles as something other than write(&double, sizeof(double)).
                                          • Sender is different architecture which represents doubles differently. Though I kind of doubt this, I believe there is some standard for how doubles are represented which is cross-architecture.
                                          • QDataStream encodes double with some extra information. Though I doubt this.

                                          the doubles are off though

                                          How "off" is "off"? Slightly wrong, or way out there?

                                          Suggestions:

                                          • You really should put those checks in on return result of QDataStream::readRawData().
                                          • Can you get the sender to send just with inPacket.Size = 1 while you get it sorted out?
                                          • Try it with plain read()s and no QDataStream. Though if that does not work you're a bit stuck.
                                          • Do you have the source code of the sender's write()ing code to examine?
                                          R Offline
                                          R Offline
                                          RobbieP
                                          wrote on 10 May 2022, 15:30 last edited by
                                          #23

                                          @JonB

                                          /* This method writes data to the UDP socket and returns the number of
                                          * bytes written or -1 for an error.  Pass in the IP and port youare sending to. */
                                          
                                          int PCSBSocketUDP::WriteData(
                                          				void *				inBuf,
                                          				int				inBufLength,
                                          				unsigned int		inDstIP,
                                          				unsigned short		inDstPort)
                                          {
                                          	sockaddr_in destAddress;
                                          	int tolen = sizeof(destAddress);
                                          	destAddress.sin_family = AF_INET;
                                          	destAddress.sin_port = htons(inDstPort);
                                          	destAddress.sin_addr.s_addr = htonl(inDstIP);
                                          	int result = sendto(mWinSocket,
                                          						 (char*)inBuf,
                                          						 inBufLength,
                                          						 0,
                                          						 (sockaddr*)&destAddress,
                                          						 tolen);
                                          
                                          	if (result == -1)
                                          	{
                                          		return -1;
                                          	}
                                          	else
                                          	{
                                          		return result;
                                          	}
                                          }
                                          

                                          and I'm sending the struct from the top of my first post with that using:

                                          m_SendSocket->WriteData((char *)&m_Packet, sizeof (fennecPacketStruct), ntohl(inet_addr(m_ipaddress.c_str())), 46456);
                                          

                                          the sender is running on this same linux machine, but it's a plugin to a flight simulator. I'll see what the return value is for readRawData next.

                                          J 1 Reply Last reply 10 May 2022, 15:39
                                          0

                                          13/29

                                          10 May 2022, 13:52

                                          • Login

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