TCP解決思路
目的:每一個客戶端連接都需要QTCPSocket開辟一條新的線程
解決方法:
-
分別繼承QTCPServer和QTCPSocket來分別實現Server和Socket(我這里是mTCPServer繼承QTCPServer,mTCPSoket繼承QTCPSokcet)
-
mTCPServer重寫incomingConnection來實現socket的自動連接,其實就是不需要connect等待連接,直接進入函數
protected:
void incomingConnection(qintptr handle);
3. 重寫incomingConnection()函數
void MyTcpServer::incomingConnection( qint32 socketDescriptor)
{
qDebug()<<tr("有新的連接 :-socketDescriptor-")<<socketDescriptor;
emit displayAccount(true); //這里是我給主界面發信號,有用戶連接
MyTcpSocket *tcptemp = new MyTcpSocket(socketDescriptor);
//初始化線程
QThread *thread = new QThread(tcptemp);
//收到客戶端發送的信息
connect(tcptemp,&MyTcpSocket::receiveData,this,&MyTcpServer::receiveDataSlot);
//客戶端斷開鏈接
connect(tcptemp,&MyTcpSocket::socketDisconnect,this,&MyTcpServer::disconnectSlot);
//客戶端斷開鏈接 關閉線程
connect(tcptemp,&MyTcpSocket::disconnected,thread,&QThread::quit);
//向socket發送信息
// 發送注冊信息
connect(this,&MyTcpServer::sendRegisterData,tcptemp,&MyTcpSocket::sendRegisterData);
//將socket移動到子線程運行
tcptemp->moveToThread(thread);
thread->start();
//將Qthread放到Map控制
clients->insert(socketDescriptor,tcptemp);
qDebug()<<tr("目前客戶端數量:")<<clients->size();
}
- mTCPSokcet解決相應的信號即可
多線程UDP解決思路
UDP的話就比較簡單了,最核心的代碼是這個
/**
* function:監聽端口
* @brief MyUDPServer::startService
*/
void MyUDPServer::startService()
{
//這里監聽端口
this->mUdpSocket = new QUdpSocket(this);
int error =this->mUdpSocket->bind(QHostAddress::Any,9999);
qDebug()<<error;
QObject::connect(mUdpSocket,SIGNAL(readyRead()),this,SLOT(readData()));
}
MyUDPServer::MyUDPServer(QObject *parent):QObject(parent)
{
}
/**
* function: 多線程讀取數據
* @brief MyUDPServer::readData
*/
void MyUDPServer::readData()
{
//獲取到傳來的數據
while(this->mUdpSocket->hasPendingDatagrams()){
//獲取數據
QByteArray array;
QHostAddress address;
quint16 port;
//根據可讀數據來設置空間大小
array.resize(this->mUdpSocket->pendingDatagramSize());
this->mUdpSocket->readDatagram(array.data(),array.size(),&address,&port); //讀取數據
//創建線程
MsgAction *msgAction = new MsgAction(array,address,port);
QThread *thread = new QThread(msgAction);
//需要封裝
qDebug()<<QThread::currentThread();
//移動到線程中
msgAction->moveToThread(thread);
thread->start();
msgAction->run();
//發送反饋數據
}
}