gpt4 book ai didi

c++ - QSerialPort - 等待来自发件人的全部数据

转载 作者:行者123 更新时间:2023-11-30 01:43:11 24 4
gpt4 key购买 nike

我正在使用串行设备。QSerialPort 在一个单独的线程中。线程是这样创建的:

QThread* serialthread = new QThread;
Serial* serial = new Serial();
serial->moveToThread(serialthread);

当数据可用时,我的线程 worker 中的这个信号被发出:

    void Serial::process()
{
serialport = new QSerialPort();
connect(this->serialport,SIGNAL(readyRead()),this,SLOT(readyToRead()));
}
void Serial::readyToRead()
{
emit SIG_dataAvailable(this->read());
}

这是读取数据并检查数据是否正确的函数 - 我的串行设备上的第二个字节表示数据包的其余部分有多长...

QByteArray Serial::read() const
{
QByteArray receivedData;
int length;
receivedData = serialport->readAll();
length = receivedData[1];
if(length != receivedData.length() - 1)
{
qDebug() << "protocol error.";
return NULL;
}
return receivedData;
}

我的问题是信号 QSerialPort::readyRead 在来自串行设备的数据在缓冲区中完成之前发出。知道如何解决这个问题吗?

最佳答案

绝对保证您会一次性获得全部数据。您可以通过某些方式解决此问题。

1) 如果您有固定大小的包裹,您可以这样做:

void foo::onSerialRead()
{
//! Is there whole datagram appears?
if (m_serial->bytesAvailable() < ::package_size) {
//! If not, waiting for other bytes
return;
}

//! Read fixed size datagram.
QByteArray package = m_serial->read(::package_size);
//! And notify about it.
emit packageReady(package);
}

2) 如果您的包裹尺寸可能不同。然后你必须在你的包中包含“hader”。此 header 应至少包含“开始”字节和数据大小(在您的情况下为第二个字节)。并且标题应该是固定大小的。然后你可以这样做:

void foo::onSerialRead()
{
static QByteArray package;
static bool isHeaderRead = false;
static quint8 startByte = 0;
static quint8 dataSize = 0;

//! Is there whole header appears?
if (m_serial->bytesAvailable() < ::header_size) {
//! If not, waiting for other bytes
return;
}

if (!isHeaderRead) {
//! Read fixed size header.
package.append(m_serial->read(::header_size));
QDataStream out(&package);

out >> startByte;

//! Check is it actually beginning of our package?
if (Q_UNLIKELY(startByte != ::protocol_start_byte)) {
return;
}
out >> dataSize;
isHeaderRead = true;
}

//! Check is there whole package available?
if (Q_LIKELY(dataSize > m_serial->bytesAvailable())) {
//! If not, waiting for other bytes.
return;
}
//! Read rest.
package.append(m_serial->read(dataSize));
//! And notify about it.
emit packageReady(package);
package.clear();
isHeaderRead = false;
}

而且绝对没有必要将您的 QSerial 放入不同的线程。

关于c++ - QSerialPort - 等待来自发件人的全部数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38169513/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com