I have provided my entire code below. Please excuse the design as I am new to Qt and this is a quick and dirty example.
What I want to do is create a QThread that manages a QTcpServer listener. I want it to be able to close listener when stopped and then reopen it when started again. Please ignore the fact that the listener may be getting leaked right now, I will tackle that issue later.
I believe the problem is that when Stop is called it invokes the m_listener->close() method on a different thread (invoked from the main thread) than the thread it was created on (it was created on the TcpServerThread). So the questions is, how to I fix it? Or how to I redesign it so I avoid this issue?
This isn't the full design, I have made a toy example that mimicks the real thing.
tcpserverthread.h
#ifndef TCPSERVERTHREAD_H
#define TCPSERVERTHREAD_H
#include <QObject>
#include <QThread>
class QTcpServer;
class TcpServerThread : public QThread
{
Q_OBJECT
public:
TcpServerThread();
void run();
void Start();
void Stop();
public slots:
void newConnection();
private:
QTcpServer* m_pListener;
};
#endif // TCPSERVERTHREAD_H
tcpserverthread.cpp
#include "tcpserverthread.h"
#include "tcpserver.h"
#include <iostream>
#include <QTcpServer>
#include <QTcpSocket>
#include <QCoreApplication>
TcpServerThread::TcpServerThread()
{
}
void TcpServerThread::run()
{
std::cout << "thread started ..." << std::endl;
std::cout << "listener starting ..." << std::endl;
m_pListener = new QTcpServer();
connect(m_pListener, SIGNAL(newConnection()), this, SLOT(newConnection()));
if(!m_pListener->listen(QHostAddress::Any, 1234))
{
std::cout << "listener could NOT START - " << m_pListener->errorString().toStdString() << std::endl;
}
else
{
std::cout << "listener SUCCESSFULLY STARTED" << std::endl;
}
// std::cout << "thread running..." << std::endl;
// m_pListener = new TcpServer();
// m_pListener->Start();
exec();
}
void TcpServerThread::newConnection()
{
qDebug() << "in new conn ... ";
//std::cout << "in new conn.." << std::endl;
QTcpSocket *soc = m_pListener->nextPendingConnection();
soc->write("hello client");
}
void TcpServerThread::Start()
{
start();
}
void TcpServerThread::Stop()
{
std::cout << "TcpServer Stopping . . . " << std::endl;
//this close is the line that causes the problem...
m_pListener->close();
this->quit();
}
main.cpp
#include <QCoreApplication>
#include <iostream>
#include <QTcpServer>
#include "tcpserver.h"
#include "tcpserverthread.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
TcpServerThread *t = new TcpServerThread();
t->Start();
t->Stop();
return a.exec();
}
If you comment out the call to t->Stop in main you can then run it and use telnet (or putty) to connect to it @ 127.0.0.1:1234.
I want to make it so it can be stopped and then started again and connections will work.
Aucun commentaire:
Enregistrer un commentaire