1

I have created a simple threaded TCP server which collects 3 lines read from the socket, and then tries to echo them back to the socket. The function echoCommand below crashes.

#include "fortunethread.h"
#include <QtNetwork>
#include <QDataStream>

FortuneThread::FortuneThread(int socketDescriptor, QObject *parent)
    : QThread(parent), socketDescriptor(socketDescriptor), in(0)
{
}

void FortuneThread::run()
{
    tcpSocketPtr = new QTcpSocket;
    if (!tcpSocketPtr->setSocketDescriptor(socketDescriptor)) {
        emit error(tcpSocketPtr->error());
        return;
    }
    in = new QDataStream(tcpSocketPtr);
    connect(tcpSocketPtr, SIGNAL(readyRead()), this, SLOT(readCommand()) );
    QThread::exec();
}

void FortuneThread::echoCommand()
{
    QString block;
    QTextStream out(&block, QIODevice::WriteOnly);
    for (QStringList::Iterator it = commandList.begin(); it != commandList.end(); ++it) {
        out << "Command: " << *it << endl;
    }

    out << endl;
    tcpSocketPtr->write(block.toUtf8());
    tcpSocketPtr->disconnectFromHost();
    tcpSocketPtr->waitForDisconnected();
}

void FortuneThread::readCommand()
{
    while (tcpSocketPtr->canReadLine())
    {
        commandList << (tcpSocketPtr->readLine()).trimmed();
    }

    if (commandList.size() > 2)
    {
        echoCommand();
    }
}

and here is the file where I connect up the slots/signals:

#include "fortuneserver.h"
#include "fortunethread.h"

#include <stdlib.h>

FortuneServer::FortuneServer(QObject *parent)
    : QTcpServer(parent)
{
}

void FortuneServer::incomingConnection(qintptr socketDescriptor)
{
    QString fortune = fortunes.at(qrand() % fortunes.size());
    FortuneThread *thread = new FortuneThread(socketDescriptor, this);
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    thread->start();
}

during or after the socket write, with this error:

**QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNativeSocketEngine(0x7f19cc002720), parent's thread is FortuneThread(0x25411d0), current thread is QThread(0x220ff90)**

Since I create the tcpSocketPtr in the run() function, I know it is in the same thread as this function. Why would the socket write fail? I should point out that the write is succeeding since I see the output on the telnet window...but still the socket write fails...


Just more info...I found that I should NOT put a slot in a QThread..not sure how to get around this, but here is my class definiation:

class FortuneThread : public QThread
{
    Q_OBJECT

public:
    FortuneThread(int socketDescriptor, QObject *parent);
    void run();

signals:
    void error(QTcpSocket::SocketError socketError);

private slots:
    void readCommand();

private:
    void echoCommand();
    int socketDescriptor;
    QDataStream *in;
    QStringList commandList;
    QTcpSocket *tcpSocketPtr;

};
4

0 回答 0