继上一篇文章
大体实现了一个与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());
}