Still having trouble deserializing binary data from another UDP source (non-qt)
-
@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?
-
@RobbieP
No, yourreadRawData()
s run sequentially, carrying on from where they got to.Possibilities:
- Sender does have some pad between end of
Name
and start ofValue
. - Sender saves
double
s as something other thanwrite(&double, sizeof(double))
. - Sender is different architecture which represents
double
s differently. Though I kind of doubt this, I believe there is some standard for howdouble
s are represented which is cross-architecture. QDataStream
encodesdouble
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 noQDataStream
. 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?
- Sender does have some pad between end of
-
/* 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.
-
@RobbieP said in Still having trouble deserializing binary data from another UDP source (non-qt):
m_SendSocket->WriteData((char *)&m_Packet, sizeof (fennecPacketStruct), ntohl(inet_addr(m_ipaddress.c_str())), 46456);
Since this sends a
fennecPacketStruct
in one chunk of bytes, why in the world are you trying to deserialize field-by-field? Assuming same machine architecture and same compiler and same definition offennecPacketStruct
with same constants for sizes, you want to just do the opposite read, likeread(&inPacket, sizeof(fennecPacketStruct))
.Meanwhile I am "unconvinced" your sender size really has an identical declaration of
struct fennecPacketStruct
as you showed? Or does it? That uses a fixed sizeSP_PACKET_SIZE
constant. But earlier your code readinPacket.Size
from the data stream, and used that to affect how much it read where. Something is fishy... -
That's what I was originally thinking a long time ago, but I can't seem to do it...it gives me this error:
/home/robbie/Documents/Programming/Fennec/mainwindow.cpp:36: error: no matching function for call to ‘QUdpSocket::read(MainWindow::fennecPacketStruct*, long unsigned int)’
../Fennec/mainwindow.cpp: In member function ‘void MainWindow::readPendingDatagrams()’:
../Fennec/mainwindow.cpp:36:24: error: no matching function for call to ‘QUdpSocket::read(MainWindow::fennecPacketStruct*, long unsigned int)’
36 | udpSocket->read(&inPacket, sizeof(fennecPacketStruct));
| ~~~~~~~~~~~~~~~~~~~~~~~~~^ -
@RobbieP
Of course that won't match. The writer code does not usefennecPacketStruct
inWriteData()
either. For qint64 QIODevice::read(char *data, qint64 maxSize) it expects achar *
, so cast it.... -
@JonB the writer is using fennecPacketStruct though isn't it? m_Packet is a fennecPacketStruct, and the writer is sending sizeof(fennecPacketStruct).
Do I cast it in the read block using another reinterpret_cast? I'm not sure how that would work, because even casting it doesn't seem to like it. Also I need to use ReadDataGram, not Read because I need the host and port that it's coming from.
-
@JonB got it!
the correct cast was (char *)&inPacket
All my values are now correct!
I'll do some sanity checking and add some value logs as well to make sure this is goign to stay consistent in the lab. Thanks much for your incredible patience and help.
-
@RobbieP said in Still having trouble deserializing binary data from another UDP source (non-qt):
the correct cast was (char *)&inPacket
Yeah. Which should have gone through as
reinterpret_cast<char *>(&inPacket)
? Not that it's much different, but keeps the wolves at bay.the writer is using fennecPacketStruct though isn't it?
But not in the definition of
PCSBSocketUDP::WriteData(void *inBuf, ...)
, orsendTo(..., (char*)inBuf)
, which are the equivalent of yourudpSocket->read(&inPacket, ...)
.
29/29