PDA

View Full Version : udp receive data problem



zxwmail
19th June 2011, 17:20
hi ,folks,i have a problem in qbytearray to float array,i received float array in udp,but return value is 0,what's wrong with me?can u help me?tks.i have searched in google.
the sender program is write by labwindows cvi.
cvi code:


float AIdat[344];
UDPWrite(writerChannel, AI_PORT, MULTICAST_ADDRESS, AIdat, sizeof(AIdat));


qt code:


const udpsize=1376;
void Widget::processPendingDatagrams()
{
qint16 packetsize;
while (udpSocket->hasPendingDatagrams()) {
QByteArray ba;
packetsize=udpSocket->pendingDatagramSize();
ba.resize(packetsize);
udpSocket->readDatagram(ba.data(), ba.size());
if (packetsize!=udpsize)
{
return;
}
// bool ok;
// ba = QByteArray::number(ba.toLongLong(&ok,16),2);
QDataStream datin(&ba,QIODevice::ReadOnly);
float firstdat;
datin>>firstdat; //first float data
if (!datin.status())
{
qDebug()<<"ok" ;
}
qDebug()<<firstdat; //it return 0 or inf;
}
}

ChrisW67
20th June 2011, 04:13
You are assuming that the transmitted array is transmitted as a single datagram and arrives as a single datagram etc. If it arrives in pieces you do nothing to accumulate the pieces (ba is discarded between while loops).

Are you sure that QDataStream's serialisation format for float is the sames as the sender's?
Is a LabView CVI float the same size and format as a C++ float?
Is there actually data in your byte array?
Is the data block just a pure list of float values, or is there an envelope structure/checksum/block size?
Are you sure the zero or inf are not the values being sent?

zxwmail
20th June 2011, 07:15
hi,chrisw67,thanks your reply.
the udp client(delphi/indy ) can received correct values,i want to use qt to replace my delphi program:).


Are you sure that QDataStream's serialisation format for float is the sames as the sender's?
so i think the problem is data format .:confused:
But I can't think of a better idea,:(
how to ?somebody can help me?

squidge
20th June 2011, 09:10
As Chris says, you may receive your datagram in multiple chunks.

Secondly, UDP is not meant to be reliable, so you may receive some data in duplicate and some data not at all.

If you want to use QDataStream, then you should use the same Qt version for both sender and receiver, to ensure compatibility.

ChrisW67
20th June 2011, 10:05
You have the data in a QByteArray. You can get a char* to the internal data buffer. You can cast that to float* if you are certain that the byte ordering is the same, and the 'float' data sent is the same format as a C++ float (not a double).

zxwmail
21st June 2011, 06:24
float* ft=ba.data();
float dat=*(ft+x);

but andbody have a Perfect solution use qt?

squidge
21st June 2011, 09:28
We don't know how the data is internally formatted, so we can't tell you the best way.

zxwmail
21st June 2011, 13:54
hi,squidge,thanks your reply,but my english is bad.
qbytearray's data type is char* ,i want to convert from char* to float array,because udp received data is float array.
if I run

float* ft=ba.data();
float dat=*(ft+x);
then
result is correct,but this is c,not c++,not qt,I believe a best way to do it with qt.

ChrisW67
21st June 2011, 21:24
What you have there won't compile without error as C or C++. This has nothing to do with Qt once you have a char* to the data in memory:


// Create some dummy data
QByteArray ba;
ba.fill(0, 10 * sizeof(float));
unsigned int size = ba.size();
char* c = ba.data();
// OR const char* cc = ba.constData();
// Make sure that ba stays in scope while you do this
// Nothing Qt below here


float* ft = reinterpret_cast<float*>(c);
// OR const float* ft = reinterpret_cast<const float*>(cc);
for (unsigned int i = 0; i < size/sizeof(float); ++i) {
std::cout << *ft++ << std:endl;
}


The caveats regarding byte order, float/double etc still apply. If it breaks you get to keep the pieces :)

squidge
21st June 2011, 23:11
I believe a best way to do it with qt.A better way in Qt is to use the streaming operators, but we don't know if these will be compatible with what you are creating at the "other end", so you may have to do something like that (or like what Chris states) to get the values you want