QSerialPort - wating for whole data from sender(QSerialPort - 等待来自发件人的全部数据)
问题描述
我正在使用串行设备.QSerialPort 位于单独的线程中.线程是这样创建的:
I'm working with a serial device. The QSerialPort is in a separate thread. Thread is created this way:
QThread* serialthread = new QThread;
Serial* serial = new Serial();
serial->moveToThread(serialthread);
当数据可用时,我的线程工作者中的这个信号会发出:
When Data is available this signal in my thread worker is emited:
void Serial::process()
{
serialport = new QSerialPort();
connect(this->serialport,SIGNAL(readyRead()),this,SLOT(readyToRead()));
}
void Serial::readyToRead()
{
emit SIG_dataAvailable(this->read());
}
这是读取数据并检查数据是否正确的函数 - 我的串行设备上的第二个字节表示数据包的其余部分有多长......
This is the function that reads the data and checks if the data is correct - the second byte on my serial device says how long the rest of the packet is...
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 在来自串行设备的数据在缓冲区中完成之前发出.知道如何解决这个问题吗?
My problem is that the signal QSerialPort::readyRead is emited before the data from the serial device is complete in the buffer. Any idea how to solve this problem?
推荐答案
绝对不保证您将在 ONCE 获得全部数据.您可以通过某些方式解决此问题.
There is absolutely NO guarantee that you'll get whole data at ONCE. You can solve this problem in some ways.
1) 如果你有固定尺寸的包裹,你可以这样做:
1) If you have fixed size package you can do something like this:
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".此标头应至少包含开始"字节和数据大小(在您的情况下为第二个字节).并且标题应该是固定大小的.然后你可以这样做:
2) If your package size may vary. Then you have to include "hader" in to your package. This header should contain at least "start" byte and data size (Its second byte in your case). And header shuld be fixed size. Then you can do something like this:
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 放到不同的线程中绝对没有意义.
And there is absolutely no point in putting your QSerial in to different thread.
这篇关于QSerialPort - 等待来自发件人的全部数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:QSerialPort - 等待来自发件人的全部数据
基础教程推荐
- 我应该对 C++ 中的成员变量和函数参数使用相同的名称吗? 2021-01-01
- 非静态 const 成员,不能使用默认赋值运算符 2022-10-09
- 为什么 RegOpenKeyEx() 在 Vista 64 位上返回错误代码 2021-01-01
- 如果我为无符号变量分配负值会发生什么? 2022-01-01
- GDB 显示调用堆栈上函数地址的当前编译二进制文 2022-09-05
- 为什么派生模板类不能访问基模板类的标识符? 2021-01-01
- 初始化列表*参数*评估顺序 2021-01-01
- 通过引用传递 C++ 迭代器有什么问题? 2022-01-01
- 为什么 typeid.name() 使用 GCC 返回奇怪的字符以及如 2022-09-16
- CString 到 char* 2021-01-01
