I have created a thread contains a QTcpServer
which accepts any incoming connections:
void Service::run() //Service class is a subclass of QThread
{
server->listen(QHostAddress::LocalHost, ServicePortNo);
// server is a private member of Service
while(server->waitForNewConnection(-1)){
QTcpSocket *socket = server->nextPendingConnection();
handle(socket); // This is a pure virtual function
}
}
in handle(QTcpSocket *socket)
:
// TimeDateService is subclass of Service
// implementation of pure virtual function handle()
void TimeDateService::handle(QTcpSocket *socket)
{
(new TimeDateSocketHandler(socket))->Start();
}
Note: TimeDateSocketHandler
is a subclass of SocketHandler
and SocketHandler
itself is a subclass of QThread
as shown in the following:
void SocketHandler::run()
{
if(!socket->waitForReadyRead(WAIT_TIMEOUT))
{
socket->disconnectFromHost();
socket->close();
return;
}
QByteArray request = socket->readAll();
QByteArray response = Serve(request); // Serve is a pure virtual function
socket->write(response);
socket->waitForBytesWritten(WAIT_TIMEOUT);
socket->disconnectFromHost();
socket->close();
}
And finally here is the TimeDateSocketHandler
QByteArray TimeDateSocketHandler::Serve(QByteArray request)
{
QByteArray response;
response.append(QTime::currentTime().toString().toUtf8());
response.append(QString(SEPARATOR).toUtf8());
response.append(QDate::currentDate().toString().toUtf8());
return response;
}
main function:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
TimeDateService timedateService;
//CalculatorService calculatorService;
//RemoteCMDService remoteCMDService;
timedateService.StartService();
//calculatorService.StartService();
//remoteCMDService.StartService();
return a.exec();
}
In the main
function I started the TimeDateService
. But when I connect to the server for retrieving time and date, server sends time and date but when the TimeDateSocketHandler
wants to close the socket the program crashes:
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects ow ned by a different thread. Current thread 3998779bf0. Receiver '' (of type 'QNat iveSocketEngine') was created in thread 39985efcd0", file kernel\qcoreapplicatio n.cpp, line 494
Can anyone help me out please how can I fix this problem, Many Thanks
Your problem is this line:
The parent "socket" lives in the TimeDateService thread, but the child will be in the TimeDateocketHandler thread. Parent and children should be in the same thread when using the Qt event loop.
Here is the relevant part of the documentation:
The solution is relatively straight-forward:
You could call the method directly with the invokeMethod method of QMetaObject. You would need to use queued connection to get the slot triggered in the separate thread.
QMetaObject::invokeMethod(new TimeDateSocketHandler(socket), SLOT(Start()), Qt::QueuedConnection);
or
Use signal and slots. This means emit a signal instead of direct invokation and then connect the other thread's corresponding slot.
TimeDateSocketHandler *timeDateSocketHandler = new TimeDateSocketHandler(socket);
connect(this, SIGNAL(socketHandled()), timeDateSocketHandler, SLOT(Start()));
emit socketHandled();
or
Use a smart pointer (like QSharedPointer) instead of raw pointer
Move to the socket handling into the other thread.