class QMMNClientThread : public QThread{ Q_OBJECT QTcpSocket * fmmnClient; //сетевой клиент QTimer * freqTimer; //таймер, в котором надо переодически слать запрос на сервер (каждые 250мс) void run();public: explicit QMMNClientThread(QObject *parent = 0); ~QMMNClientThread(); QString remoteHost; quint16 remotePort;signals:public slots:private slots: void readyRead(); void onConnected(); void onDisconnected(); void onError(); void doRequest();};
#include <memory.h>#include <QObject>#include "mmn_client.h"#include "qmmnclientthread.h"QMMNClientThread::QMMNClientThread(QObject *parent) : QThread(parent){ remoteHost = "127.0.0.1"; remotePort = 10000; freqTimer = new QTimer; freqTimer->setInterval(250); fmmnClient->moveToThread(this); freqTimer->moveToThread(this); connect(fmmnClient,SIGNAL(connected()),this,SLOT(onConnected())); connect(fmmnClient,SIGNAL(disconnected()),this,SLOT(onDisconnected())); connect(fmmnClient,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(onError())); connect(fmmnClient,SIGNAL(readyRead()),this,SLOT(readyRead())); connect(freqTimer,SIGNAL(timeout()),this,SLOT(doRequest()));}QMMNClientThread::~QMMNClientThread(){ freqTimer->stop(); //надо остановить таймер fmmnClient->close(); //закрыть соединение delete fmmnClient; //удалить объекты delete freqTimer; if(frawBuffer) free(frawBuffer); //освободить память буфера приема}void QMMNClientThread::run(){ fmmnClient->connectToHost(remoteHost,remotePort); //первая попытка соединения exec(); //запускаю петлю событий потока}void QMMNClientThread::readyRead(){ //здесь буду обрабатывать принятые данные (порядка 4Кб)}void QMMNClientThread::onConnected(){//при подключении к серверу начинаю делать запросы данных freqTimer->start(250);}void QMMNClientThread::onDisconnected(){//если сервер отключил, то freqTimer->stop(); //остановить запросы fmmnClient->close(); //закрыть сокет sleep(freconnTimeot); //ждем 2 секунды fmmnClient->connectToHost(remoteHost,remotePort); //пытаемся подключиться}//пока тоже самое как и при отключенииvoid QMMNClientThread::onError(){ freqTimer->stop(); fmmnClient->close(); sleep(freconnTimeot); fmmnClient->connectToHost(remoteHost,remotePort);}void QMMNClientThread::doRequest(){ //здесь надо отправить небольшой пакет данных по этому же сокету}
QMMNClientThread::~QMMNClientThread(){ freqTimer->stop(); //надо остановить таймер fmmnClient->close(); //закрыть соединение <<--------здесь вылетает окно с аварийным закрытием программы delete fmmnClient; //удалить объекты delete freqTimer; if(frawBuffer) free(frawBuffer); //освободить память буфера приема}
class QMMNClient : public QObject{ Q_OBJECT QTcpSocket * fsocket; QTimer * freqTimer; QMutex * fmutex; quint16 fblockSize; quint16 fleftBytes; quint32 freconnTimeot;public: explicit QMMNClient(QObject *parent = 0); ~QMMNClient(); int id; QString remoteHost; quint16 remotePort; void connectToServer(); void disconnectFromServer(); void moveToThread(QThread *thread); bool safeGetData(mmn_frame_t * destFrame, size_t frameSize);signals: void connected(int id); void disconnected(int id); void frameReceived(int id);private slots: void readyRead(); void onConnected(); void onDisconnected(); void doRequest();public slots: void sendRequest();};//реализацияQMMNClient::QMMNClient(QObject *parent) : QObject(parent){ id = 0; fsocket = new QTcpSocket; remoteHost = "127.0.0.1"; remotePort = 10000; freconnTimeot = 2; freqTimer = new QTimer; freqTimer->setInterval(250); fmutex = new QMutex;//эти соыбтия обрабатываю внутри потока сетевого клиента connect(fsocket,SIGNAL(connected()),this,SLOT(onConnected())); connect(fsocket,SIGNAL(disconnected()),this,SLOT(onDisconnected())); connect(fsocket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(onDisconnected())); connect(fsocket,SIGNAL(readyRead()),this,SLOT(readyRead())); //здесь читаю connect(freqTimer,SIGNAL(timeout()),this,SLOT(doRequest())); //переодический запрос на сервер}QMMNClient::~QMMNClient(){ freqTimer->stop(); fsocket->abort(); delete fsocket; delete freqTimer; delete fmutex; if(frawBuffer) free(frawBuffer);}void QMMNClient::readyRead(){ if(fblockSize==0) { if(fsocket->bytesAvailable()<sizeof(scb_msg_t)) return; fblockSize = fsocket->read(frawBuffer,sizeof(scb_msg_t)); if(fframeBuffer.msg_head->size==0) { fblockSize = 0; return; } qDebug("block %d\n, header.size %d",fblockSize,fframeBuffer.msg_head->size); } fblockSize=fsocket->bytesAvailable(); fleftBytes = fframeBuffer.msg_head->size-sizeof(scb_msg_t); if(fblockSize>=(fleftBytes)) { fmutex->lock(); fblockSize = fsocket->read(&frawBuffer[sizeof(scb_msg_t)],fleftBytes); fmutex->unlock(); qDebug("fblockSize %d\n",fblockSize); fblockSize = 0; emit frameReceived(id); //надо это событие обработать в потоке GUI }}bool QMMNClient::safeGetData(mmn_frame_t * destFrame, size_t frameSize){ if(destFrame && (frameSize==fframeSize)) { fmutex->lock(); qMemCopy(destFrame,&fframeBuffer,fframeSize); fmutex->unlock(); return true; } return false;}void QMMNClient::onConnected(){ fblockSize = 0;// qDebug("connected channel %d\n",id); emit connected(id); freqTimer->start(250);}void QMMNClient::onDisconnected(){// qDebug("disconnected channel %d\n",id); freqTimer->stop(); fsocket->close(); emit disconnected(id); sleep(freconnTimeot); fsocket->connectToHost(remoteHost,remotePort);}void QMMNClient::doRequest(){ sendRequest();}void QMMNClient::connectToServer(){ fsocket->connectToHost(remoteHost,remotePort);}void QMMNClient::disconnectFromServer(){ fsocket->close();}void QMMNClient::sendRequest(){ fsocket->write((const char*)&frequest,frequestSize); //отправляем некую структурку на сервер, на которую он должен ответить}void QMMNClient::moveToThread(QThread *thread){ QObject::moveToThread(thread); //двигаем себя в нужный поток if(fsocket) fsocket->moveToThread(thread); //сокет if(freqTimer) freqTimer->moveToThread(thread); //и таймер}
class QMMNClientThread : public QThread{ Q_OBJECT void run();public: explicit QMMNClientThread(QObject *parent = 0); ~QMMNClientThread(); QMMNClient * mmnClient;signals:public slots:};// реализацияQMMNClientThread::QMMNClientThread(QObject *parent) : QThread(parent){ mmnClient = new QMMNClient; mmnClient->moveToThread(this);}QMMNClientThread::~QMMNClientThread(){ quit(); wait();}void QMMNClientThread::run(){ mmnClient->connectToServer(); exec();}
mmnClientThread = new QMMNClientThread(this); mmnClientThread->mmnClient->remoteHost = ecHost[i]; mmnClientThread->mmnClient->remotePort = ecPort[i]; connect(mmnClientThread->mmnClient,SIGNAL(frameReceived(int)),this,SLOT(data_receive(int)),Qt::BlockingQueuedConnection);//здесь будет обращение к GUI connect(mmnClientThread->mmnClient,SIGNAL(connected(int)),this,SLOT(chan_connected(int))); connect(mmnClientThread->mmnClient,SIGNAL(disconnected(int)),this,SLOT(chan_disconnected(int))); mmnClientThread->start();