从QTcpSocket读取(多个)值(快速)

时间:2017-08-02 14:01:27

标签: c++ qt qtcpsocket qdatastream

我使用的测量设备使用最高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读取多个值?

答案:在评论中找到答案。

更新(回答一些问题):

  • 字节的最大速率: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;
}

一次又一次地这样做,我有时会得到状态= -1(读得太多),有时候不会。我如何获得&#34;尺寸&#34;流?

1 个答案:

答案 0 :(得分:2)

您的代码有几个错误。

在使用QDataStream的同时,您正在从套接字直接读取。这可能会破坏东西。

此外,您的代码假设您的应用程序将接收与其他端发送的数据相同的数据块。你没有这样的保修!您可能会收到以帧中间结尾的块数据。它只是运气好,或者你忽略了你的应用程序的一些错误。

这应该是这样的:

while(true)
if (mysock->waitForReadyRead()) // IMO doing such loop is terrible approach
// but this is Out of the scope of question, so ignoring that
{
    while (true)
    {
        stream.startTransaction();
        float result;
        qint32 somedata
        stream >> somedata >> result; // I do not know binary format your application is using

        if (!in.commitTransaction())
            break;

        AddDataToModel(result, somedata);
    } 
}

<小时/> 编辑:

来自评论:

  

如果我错了,请纠正我,但如果我想丢弃2个字节,我需要做&#34; stream&gt;&gt; someint(2字节)&gt;&gt; somefloat(4字节)&#34;?如何在流中处理多个值?

qint16 toBeDiscarded;
float value; 
// note stream.setFloatingPointPrecision(QDataStream::SinglePrecision); 
// is needed to read float as 32 bit floating point number

stream >> toBeDiscarded >> value;
ProcessValue(value);