头文件CSerialThread.h
#pragma once
#include <QThread>
#include <QTcpSocket>
#include <QByteArray>
class CSerialThread : public QThread
{
Q_OBJECT
public:
CSerialThread(QObject *parent = nullptr);
~CSerialThread();
void Stop();
protected:
void run() override;
private slots:
void OnReadyRead();
void OnThreadFinished();
private:
void SendToServer(const QByteArray& res);
private:
QString id;
quint16 port;
QTcpSocket* m_Socket;
QByteArray m_buffer;
int m_nPackSize;
};
实现CSerialThread.cpp
#include "CSerialThread.h"
#include "CCommandInterface.h"
#include "CMutilQueues.h"
#include <QDebug>
#include "CGoogleLog.h"
#include <QDataStream>
#include "CConfig.h"
CSerialThread::CSerialThread(QObject *parent)
: QThread(parent)
{
this->moveToThread(this);
connect(this, &QThread::finished, this, &CSerialThread::OnThreadFinished);
m_Socket = nullptr;
id = QString::fromStdString(CCfgInstance::Get()->GetValue("server_ip"));
port = std::stoi(CCfgInstance::Get()->GetValue("server_port"));
m_nPackSize = std::stoi(CCfgInstance::Get()->GetValue("pack_size"));
}
CSerialThread::~CSerialThread()
{
}
void CSerialThread::Stop()
{
exit();
wait();
}
void CSerialThread::run()
{
m_Socket = new QTcpSocket(this);
m_Socket->connectToHost(id, port);
if (m_Socket->waitForConnected(30000))
{
connect(m_Socket, &QTcpSocket::readyRead, this, &CSerialThread::OnReadyRead, Qt::QueuedConnection);
LOG(INFO) << "服务器连接成功";
SendToServer("Connected Server");
exec();
}
else
{
if (m_Socket->isOpen())
{
m_Socket->close();
}
return;
}
}
void CSerialThread::SendToServer(const QByteArray& res)
{
QByteArray byt;
QDataStream data_stream(&byt, QIODevice::WriteOnly);
data_stream.setByteOrder(QDataStream::BigEndian);
data_stream << res;
m_Socket->write(byt);
m_Socket->flush();
}
void CSerialThread::OnReadyRead()
{
if (m_Socket->bytesAvailable() <= 0)
{
return;
}
//临时获得从缓存区取出来的数据,但是不确定每次取出来的是多少。
QByteArray buffer;
//如果是信号readyRead触发的,使用readAll时会一次把这一次可用的数据全总读取出来
buffer = m_Socket->readAll();
uint uMessLen = buffer.size();
LOG(INFO) << "Mess Len: " << uMessLen;
//上次缓存加上这次数据
m_buffer.append(buffer);
ushort uTypeId;
//分包发送
int nTotalLen = (int)m_buffer.size();
while (nTotalLen)
{
QDataStream packet(m_buffer);
packet.setByteOrder(QDataStream::BigEndian);
if (nTotalLen < m_nPackSize)//不够发送数据
{
break;
}
//读取一包数据
QByteArray bf;
bf.resize(m_nPackSize);
packet.readRawData(bf.data(), m_nPackSize);
//将包发送给处理队列,(这块根据自己需求来写。)
std::shared_ptr<CCommandInterface> pCommand(new CCommandSerial(bf));
shared_ptr<CCommandSerial> ptrSeral = std::dynamic_pointer_cast<CCommandSerial>(pCommand);
if (ptrSeral == nullptr)
{
LOG(INFO) << "dynamic_pointer_cast error";
continue;
}
ptrSeral->ParseCommand();
CMutilQueues::PutData(EQueueId::SERIAL, pCommand);
//缓存多余的数据
buffer = m_buffer.right(nTotalLen - uMessLen);
//更新长度
nTotalLen = buffer.size();
//更新多余数据
m_buffer = buffer;
}
}
void CSerialThread::OnThreadFinished()
{
LOG(INFO) << "OnThreadFinished";
}