【发布时间】:2018-01-09 19:27:30
【问题描述】:
我正在使用一个测量设备,它使用最高 70 kHz 的 tcp 套接字发送(二进制)浮点值。
我的目标是尽可能快地读取这些值并将它们用于我程序的其他部分。
到目前为止,我能够使用 QTcpSocket 和 QDataStream 按值提取值:
首先我创建套接字并将流连接到它
mysock = new QTcpSocket(this);
mysock->connectToHost(ip, port);
QDataStream stream(mysock);
stream.setByteOrder(QDataStream::LittleEndian);
stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
然后我从套接字读取并将流数据写入我的浮点值
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;
}
}
当我测量 while(true) 循环的迭代频率时,我能够达到大约 30 kHz。 每次读取多个值我可以达到 70 Khz。 (不考虑其他可能会减慢我速度的计算)
我的问题是:
- 如果我一次读取多个值,如何从 QDataStream 中提取这些值?我需要一个 6 个字节的间距,其中只有 4 个字节包含该值。
答案:在我的情况下,有 2 个字节(垃圾)后跟已知数量的值,例如浮点数为 4 个字节,另一个浮点数为 4 个字节,uint16 为 2 个字节。
stream >> trashuint16 >> resultfloat1 >> resultfloat2 >> resultuint16
- 扩展 1:我可以配置我的设备以发送需要写入不同变量的不同类型(int、float)的不同值。
答案:相同。
- 是否有更有效的方法从 QTcpSocket 读取多个值?
答案:在 cmets 中回答。
更新(回答一些问题):
- 以字节为单位的最大速率:70 kHz x 6 字节(对于一个值)= 420 kB/s(似乎没有那么多:))
更新 2
-
新问题:当我开始交易(使用
stream.startTransaction)时,我想知道二进制代码流中的内容。 - 我不明白
QDataStream::startTransaction的工作原理。将读取多少字节?我没有使用>>提取的数据会怎样?
我尝试了以下方法:
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;
}
一次又一次地这样做,我有时会得到 status = -1(读取太多),有时不会。如何获取流的“大小”?
【问题讨论】:
-
你能告诉我最大速率是多少字节吗?
-
读取更大的字节块并对其进行计数,以确保所有字节都在您的套接字缓冲区中接收。然后在循环之前删除
QByteArray a。不要在循环中定义新的内存部分,定义一个缓冲区然后附加到它。 -
首先考虑Qt是一个事件驱动的框架。使用 while(true) 不是最好的方法。 This answer 应该有帮助。
-
我同意@TheDarkKnight。可能你看到了一个性能问题,你想:“让我们使用线程来提高性能”,而不是理解这个问题。多线程很难。它的错误非常难以找到,因此由于您是新手,所以在您获得一些经验之前根本不要使用它们。它会为您节省很多时间和痛苦。
标签: c++ qt qtcpsocket qdatastream