QTcpServer多线程资源释放
2018-02-27 09:59
435 查看
采用重写QThread而非moveToThread的方法,难点在于资源的释放.因为一个socket对应一个thread,所以可以利用 socket断开或错误->删除socket->线程exit(0)的方式
TcpServer.cpp#include "tcpserver.h"
#include "tcpthread.h"
#include "../mainwindow.h"
#include <QDebug>
TcpServer::TcpServer(QObject *parent) : QTcpServer(parent)
{
qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
}
void TcpServer::startServer()
{
if(!this->listen(QHostAddress(MainWindow::ip_combo_text),MainWindow::port_spin_num))
{
qDebug()<<"server can not listen!";
}
this->setMaxPendingConnections(maxThreadNum);
}
void TcpServer::stopServer()
{
//clear thread
emit sig_disconnect_socket();
//_threadVec.clear();
//stop server
this->close();
}
void TcpServer::incomingConnection(qintptr handle)
{
//校验线程数量,保证当前线程数小于最大线程数
if(_threadVec.count()>=maxThreadNum)
{
return;
}
TcpThread *thread=new TcpThread(handle,this);
_threadVec.append(thread);
connect(thread,&TcpThread::finished,thread,&TcpThread::deleteLater);
//用于close server时清空socket,然后socket线程清空线程
connect(thread,&TcpThread::sig_socket_inited,[&,thread](){
connect(this,&TcpServer::sig_disconnect_socket,thread->socket,&TcpSocket::disconnectFromHost,Qt::QueuedConnection);
});
thread->start();
}TcpThread.cpp#include "tcpthread.h"
#include <QDebug>
#include "tool/helper.h"
TcpThread::TcpThread(qintptr handle, QObject *parent) : QThread(parent)
{
_handle=handle;
}
TcpThread::~TcpThread()
{
qDebug()<<"TcpThread::~TcpThread()";
}
void TcpThread::run()
{
socket=new TcpSocket;
if(!socket->setSocketDescriptor(_handle))
{
qDebug()<<socket->errorString();
return;
}
emit sig_socket_inited();
_ip=socket->peerName();
_port=socket->peerPort();
connect(socket,&TcpSocket::readyRead,this,&TcpThread::handleReadyRead,Qt::DirectConnection);
connect(socket,&TcpSocket::disconnected,this,&TcpThread::handleDisconnected,Qt::DirectConnection);
connect(socket,static_cast<void(QAbstractSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error),this,&TcpThread::handleSocketError,Qt::DirectConnection);
exec();
}
void TcpThread::handleReadyRead()
{
while(!socket->atEnd())
{
readBuf=socket->readAll();
readDB+=readBuf;
}
Helper::isZhenOK(readDB);
}
void TcpThread::handleDisconnected()
{
qDebug()<<"disconnected"<<_port;
//disconnect之后,delete之前可能会有error,两者操作上有重复,所以要删掉一个
disconnect(socket,static_cast<void(QAbstractSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error),this,&TcpThread::handleSocketError);
socket->deleteLater();
socket=NULL;
exit(0);
}
void TcpThread::handleSocketError(QAbstractSocket::SocketError error)
{
qDebug()<<"socketerror"<<_port;
//出现error之后,delete之前会disconnect,两者操作上有重复,所以要删掉一个
disconnect(socket,&TcpSocket::disconnected,this,&TcpThread::handleDisconnected);
socket->deleteLater();
socket=NULL;
exit(0);
}
MainWindow.cppconnect(qApp,&QApplication::aboutToQuit,server,&TcpServer::stopServer);可以重写析构函数,看thread和socket是否析构
TcpServer.cpp#include "tcpserver.h"
#include "tcpthread.h"
#include "../mainwindow.h"
#include <QDebug>
TcpServer::TcpServer(QObject *parent) : QTcpServer(parent)
{
qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
}
void TcpServer::startServer()
{
if(!this->listen(QHostAddress(MainWindow::ip_combo_text),MainWindow::port_spin_num))
{
qDebug()<<"server can not listen!";
}
this->setMaxPendingConnections(maxThreadNum);
}
void TcpServer::stopServer()
{
//clear thread
emit sig_disconnect_socket();
//_threadVec.clear();
//stop server
this->close();
}
void TcpServer::incomingConnection(qintptr handle)
{
//校验线程数量,保证当前线程数小于最大线程数
if(_threadVec.count()>=maxThreadNum)
{
return;
}
TcpThread *thread=new TcpThread(handle,this);
_threadVec.append(thread);
connect(thread,&TcpThread::finished,thread,&TcpThread::deleteLater);
//用于close server时清空socket,然后socket线程清空线程
connect(thread,&TcpThread::sig_socket_inited,[&,thread](){
connect(this,&TcpServer::sig_disconnect_socket,thread->socket,&TcpSocket::disconnectFromHost,Qt::QueuedConnection);
});
thread->start();
}TcpThread.cpp#include "tcpthread.h"
#include <QDebug>
#include "tool/helper.h"
TcpThread::TcpThread(qintptr handle, QObject *parent) : QThread(parent)
{
_handle=handle;
}
TcpThread::~TcpThread()
{
qDebug()<<"TcpThread::~TcpThread()";
}
void TcpThread::run()
{
socket=new TcpSocket;
if(!socket->setSocketDescriptor(_handle))
{
qDebug()<<socket->errorString();
return;
}
emit sig_socket_inited();
_ip=socket->peerName();
_port=socket->peerPort();
connect(socket,&TcpSocket::readyRead,this,&TcpThread::handleReadyRead,Qt::DirectConnection);
connect(socket,&TcpSocket::disconnected,this,&TcpThread::handleDisconnected,Qt::DirectConnection);
connect(socket,static_cast<void(QAbstractSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error),this,&TcpThread::handleSocketError,Qt::DirectConnection);
exec();
}
void TcpThread::handleReadyRead()
{
while(!socket->atEnd())
{
readBuf=socket->readAll();
readDB+=readBuf;
}
Helper::isZhenOK(readDB);
}
void TcpThread::handleDisconnected()
{
qDebug()<<"disconnected"<<_port;
//disconnect之后,delete之前可能会有error,两者操作上有重复,所以要删掉一个
disconnect(socket,static_cast<void(QAbstractSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error),this,&TcpThread::handleSocketError);
socket->deleteLater();
socket=NULL;
exit(0);
}
void TcpThread::handleSocketError(QAbstractSocket::SocketError error)
{
qDebug()<<"socketerror"<<_port;
//出现error之后,delete之前会disconnect,两者操作上有重复,所以要删掉一个
disconnect(socket,&TcpSocket::disconnected,this,&TcpThread::handleDisconnected);
socket->deleteLater();
socket=NULL;
exit(0);
}
MainWindow.cppconnect(qApp,&QApplication::aboutToQuit,server,&TcpServer::stopServer);可以重写析构函数,看thread和socket是否析构
相关文章推荐
- QTcpServer多线程实现
- QTcpServer多线程实现
- 一个非常有趣的QTcpServer多线程编程问题
- 多线程的QTcpServer
- 创建一个多线程的QTcpServer
- QTcpServer多线程实现
- 新手易步入的Qt中QTcpServer多线程误区
- QTcpServer多线程实现
- Qt: 释放窗口资源
- QTcpServer多个TcpSocket连接
- Qt 5.8 QTcpServer 无法监听局域网 ip 地址问题
- QTcpServer+QTcpSocket使用整理
- qt QTcpServer与QTcpSocket通讯
- Qt5.5中QTcpserver的注意细节(默认监听与IPv6格式等)
- QTcpserver listen
- Qt之QTcpServer/QTcpSocket简单收发信息(2)
- Qt关闭窗体自动释放资源
- 多线程中的资源释放
- QTcpServer、QTcpSocket、QUdpSocket在聊天程序上的应用
- QTcpServer QTcpScoket通讯