I'm using a measurement device which sends (binary) float values using a tcp socket with up to 70 kHz.
My goal is to read these values as fast as possible and use them in other parts of my program.
Till now I'm able to extract value by value using a QTcpSocket and QDataStream:
First I create the socket and connect the stream to it
mysock = new QTcpSocket(this);
mysock->connectToHost(ip, port);
QDataStream stream(mysock);
stream.setByteOrder(QDataStream::LittleEndian);
stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
Then I read from the socket and write the stream data to my float value
while(true) //only for test purpose (dont stop reading)
if (mysock->waitForReadyRead())
{
while (mysock->bytesAvailable() >= 6)
{
QByteArray a = mysock->read(6); //each value sent is 6 bytes long
stream.skipRawData(2); //first 2 bytes don't belong to the number
float result;
stream >> result;
//qDebug()<<result;
}
}
When I measure the iteration frequency of the while(true) loop I'm able to achieve about 30 kHz. Reading multiple values per read I can reach up to 70 Khz. (Not taking other calculations into account which might slow me down)
My questions are:
- If I read multiple values at once, how do I extract these values from the QDataStream? I need a 6 bytes spacing with only 4 bytes containing the value.
Answer: In my case there is 2 bytes (trash) followed by a known number of values, for example 4 bytes for a float, 4 bytes for another float, 2 bytes for an uint16.
stream >> trashuint16 >> resultfloat1 >> resultfloat2 >> resultuint16
- Expands 1: I can configure my device to send different values of different type (int, float) which need to be written to different variables.
Answer: Same.
- Is there a more efficient way to read many values from a QTcpSocket?
Answer: Anwered in the comments.
Update (to answer some questions):
- Max rate in Bytes: 70 kHz x 6 Byte (for one value) = 420 kB/s (Doesnt seem that much :))
Update 2
- New Question: When i start a transaction (using
stream.startTransaction
) I would like to know whats inside that stream in binary code. - I dont understand how
QDataStream::startTransaction
works. How many bytes will be read? what happens with the data I dont extract using>>
?
I've tried the following:
if (mysock->waitForReadyRead())
{
stream.startTransaction();
char *c = new char[40];
stream.readRawData(c, 40); //I want to know whats really inside
QByteArray a(c);
qDebug() << a <<stream.status();
if (!stream.commitTransaction())
break;
}
Doing this again and again, I'll sometimes get status = -1 (read too much) and sometimes not. How do I get the "size" of the stream?