QT/C++ TCP多线程客户端(收发线程分离,自动粘包处理,自动数据包成型)
时间: 2024-10-11 15:12:01 浏览: 6
在C++中使用Qt库创建TCP多线程客户端时,我们可以使用QThread和信号槽机制来实现线程分离、自动粘包处理以及数据包的发送和接收。以下是一个简化的示例,展示了如何创建两个独立的线程,一个用于接收(接收线程),另一个用于发送(发送线程),并使用缓冲区进行自动粘包处理:
```cpp
#include <QObject>
#include <QTcpSocket>
#include <QThread>
#include <QBuffer>
#include <QDebug>
class ReceiveThread : public QThread {
public:
explicit ReceiveThread(QObject* parent = nullptr) : QThread(parent), socket(nullptr) {}
private slots:
void run() override {
socket = new QTcpSocket(parent());
if (!socket->connectToHost("localhost", 12345)) {
qCritical() << "Failed to connect: " << socket->errorString();
return;
}
while (true) {
QByteArray buffer;
// 设置接收缓冲区大小,根据实际网络情况调整
qint64 bytesReceived = socket->read(buffer, 1024);
if (bytesReceived <= 0) {
qCritical() << "Connection closed or error: " << socket->errorString();
break;
}
handleReceivedData(buffer);
}
delete socket;
}
virtual void handleReceivedData(const QByteArray& data) = 0;
protected:
~ReceiveThread() override {}
};
class sendDataObject : public QObject {
public slots:
void sendData(const QByteArray& message) {
SendThread* sendThread = new SendThread(this);
sendThread->moveToThread(sendThread);
connect(sendThread, &SendThread::sent, this, &sendDataObject::dataSent);
sendThread->start();
sendThread->sendData(message);
// Wait for the sent signal to be emitted before continuing
QTimer::singleShot(0, this, [this]() { emit dataSent(); });
}
signals:
void dataSent();
private:
SendThread* sendThread;
};
class SendThread : public QThread {
public:
explicit SendThread(QObject* parent = nullptr) : QThread(parent), socket(nullptr) {}
private slots:
void start() override {
socket = new QTcpSocket(parent());
if (!socket->connectToHost("localhost", 12345)) {
qCritical() << "Failed to connect: " << socket->errorString();
quit();
return;
}
emit sent();
sendData(socket);
}
void sendData(QTcpSocket* socket) {
QByteArray message = ...; // Your message formation logic here
socket->write(message);
}
protected:
~SendThread() override {}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
sendDataObject obj;
obj.sendData("Hello Server!");
return app.exec();
}
```
在这个例子中,`ReceiveThread`负责连接到服务器并接收数据,`handleReceivedData`函数子类需要覆盖以处理接收到的数据。`SendThread`负责建立连接并向服务器发送数据。`sendDataObject`包含了发送逻辑,它启动一个发送线程并将消息传递给它。
注意,这个示例中的“自动粘包处理”主要依赖于接收端设置合适的接收缓冲区大小。此外,为了防止数据丢失,通常会在发送端添加适当的分片或确认机制,这可能超出本示例范围。