继上一篇文章
大体实现了一个与UI线程分离的SOCKET封装类
即后台线程负责收发数据包,有数据到来则通知UI线程
UI线程发送数据时通知后台线程(异步)
嗯,大概是这个意思
#pragma once #include <QTcpSocket> #include <QByteArray> #include "XBackgroundWorker.h" class CXAsyncSocket : public CXBackgroundWorker { Q_OBJECT public: explicit CXAsyncSocket(void); virtual ~CXAsyncSocket(void); private: QTcpSocket *m_TcpSocket; private slots: void Construct_Invokee(); void Destruct_Invokee(); void Connect_Invokee(char *host, quint16 port); void DisConnect_Invokee(); void Send_Invokee(QByteArray buffer); public: static void RegisterMetaTypes(); // 下面三个函数用于前台线程 void Connect(char *host, quint16 port); void DisConnect(); void Send(QByteArray buffer); private slots: // 执行环境为后台线程 void OnReceive(); protected: // 执行环境为后台线程 virtual void OnReceiveBuffer(QByteArray &buffer) = 0; signals: void OnConnect(); void OnDisConnect(); void OnException(QAbstractSocket::SocketError); };
#include "XAsyncSocket.h" CXAsyncSocket::CXAsyncSocket() { m_TcpSocket = NULL; QMetaObject::invokeMethod(this, "Construct_Invokee", Qt::BlockingQueuedConnection); Q_ASSERT(m_TcpSocket != NULL); } CXAsyncSocket::~CXAsyncSocket(void) { Q_ASSERT(m_TcpSocket != NULL); QMetaObject::invokeMethod(this, "Destruct_Invokee", Qt::BlockingQueuedConnection); Q_ASSERT(m_TcpSocket == NULL); } void CXAsyncSocket::RegisterMetaTypes() { qRegisterMetaType<char*>("char*"); qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError"); } void CXAsyncSocket::Construct_Invokee() { m_TcpSocket = new QTcpSocket; connect(m_TcpSocket, SIGNAL(connected()), this, SIGNAL(OnConnect()), Qt::QueuedConnection); connect(m_TcpSocket, SIGNAL(disconnected()), this, SIGNAL(OnDisConnect()), Qt::QueuedConnection); connect(m_TcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(OnException(QAbstractSocket::SocketError)), Qt::QueuedConnection); connect(m_TcpSocket, SIGNAL(readyRead()), this, SLOT(OnReceive()), Qt::QueuedConnection); } void CXAsyncSocket::Destruct_Invokee() { m_TcpSocket->disconnect(); m_TcpSocket->abort(); delete m_TcpSocket; m_TcpSocket = NULL; } void CXAsyncSocket::Connect_Invokee(char *host, quint16 port) { m_TcpSocket->connectToHost(host, port); } void CXAsyncSocket::Connect(char *host, quint16 port) { QMetaObject::invokeMethod(this, "Connect_Invokee", Qt::QueuedConnection, Q_ARG(char*, host), Q_ARG(quint16, port)); } void CXAsyncSocket::DisConnect_Invokee() { m_TcpSocket->abort(); } void CXAsyncSocket::DisConnect() { QMetaObject::invokeMethod(this, "DisConnect_Invokee", Qt::QueuedConnection); } void CXAsyncSocket::Send_Invokee(QByteArray buffer) { m_TcpSocket->write(buffer); } void CXAsyncSocket::Send(QByteArray buffer) { QMetaObject::invokeMethod(this, "Send_Invokee", Qt::QueuedConnection, Q_ARG(QByteArray, buffer)); } void CXAsyncSocket::OnReceive() { OnReceiveBuffer(m_TcpSocket->readAll()); }