Threaded Echo Server - error creating children with right parent
-
I created a simple threaded echo server (based on the threaded fortune server example). It correctly creates a new thread when a client connects, and the readCommand slot was correctly called when new text lines are sent from the client, however, when the echoCommand function is called I get this error as soon as the tcpSocket->write is called (line 48 in the code below):
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNativeSocketEngine(0x7f7ab8002980), parent's thread is ClientThread(0x239b4f0), current thread is QThread(0x2069f90)I read a lot about signals and slots and figured it has something to do with the write starting a new thread but the parent not being right. So I changed my code to start the thread like this:
@Server::Server(QObject *parent)
: QTcpServer(parent)
{
}void Server::incomingConnection(qintptr socketDescriptor)
{
QThread *t = new QThread();
ClientThread *thread = new ClientThread(socketDescriptor, t);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->moveToThread(t);
t->start();
}@but now the readCommand slot never fires (see line 26). I'm missing something basic here...can someone tell me how to fix this mess?
@#include "clientthread.h"
#include <QtNetwork>
#include <QDataStream>ClientThread::ClientThread(int socketDescriptor, QObject *parent)
: threadparent(parent), socketDescriptor(socketDescriptor), in(0)
{}
void ClientThread::run()
{
tcpSocketPtr = new QTcpSocket;if (!tcpSocketPtr->setSocketDescriptor(socketDescriptor)) { emit error(tcpSocketPtr->error()); return; } // Connect data stream to socket in = new QDataStream(tcpSocketPtr); // When data is present on incoming, read characters for a command connect(tcpSocketPtr, SIGNAL(readyRead()), this, SLOT(readCommand()) ); // Idle and wait for signals QThread::exec();
}
// Echo the command then quit
void ClientThread::echoCommand()
{
qDebug() << "in echoCommand" << endl;QString block; QTextStream out(&block, QIODevice::WriteOnly); for ( QStringList::Iterator it = commandList.begin(); it != commandList.end(); ++it ) { out << "Command: " << *it << endl; } out << endl; qDebug() << "About to write to socket:" << endl << block.toUtf8(); tcpSocketPtr->write(block.toUtf8()); qDebug() << "About to disconnect from socket" << endl; tcpSocketPtr->disconnectFromHost(); qDebug() << "About to wait for disconnect from socket" << endl; tcpSocketPtr->waitForDisconnected();
}
// Chars in input connection, read into buffer and call command process
// If a newline is present (for each command)
void ClientThread::readCommand()
{
while (tcpSocketPtr->canReadLine())
{
commandList << (tcpSocketPtr->readLine()).trimmed();
}
qDebug() << "CommandList size: " << commandList.size() << endl;
if (commandList.size() > 2)
{
echoCommand();
}
}@