Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Threading for TCP server



  • Hi, I am trying to use multi-threading for my tcpserver. The code works fine but I get QObject: Cannot create children for a parent that is in a different thread. (Parent is QTcpSocket(0x2ef5150), parent's thread is QThread(0x1728280), current thread is MyThread(0x2ef45a0) which I don't know why it arises and how to solve it. Below is my code:

    #include "myserver.h"
    
    MyServer::MyServer(QObject *parent):QTcpServer(parent)
    {
    
    }
    
    void MyServer::StartServer()
    {
        if(!this -> listen(QHostAddress::LocalHost, 1234))
        {
            qDebug()<<"Could not start server";
        }else
        {
            qDebug()<<"Start server, Listening...";
        }
    }
    
    void MyServer::incomingConnection(qintptr socketDescriptor)
    {
        qDebug()<<"Connecting...";
        MyThread *thread = new MyThread(socketDescriptor);
        connect(thread, &MyThread::finished, thread, &MyThread::deleteLater);
        thread -> start();
    
    }
    
    
    MyThread::MyThread(qintptr ID, QObject *parent):QThread(parent)
    {
        this -> socketDescriptor = ID;
        socket = new QTcpSocket;
    }
    
    void MyThread::run()
    {
        //thread starts here
        qDebug()<<"Starting thread";
        if(!socket -> setSocketDescriptor(socketDescriptor))
        {
            emit error(socket->error());
        }
    
        connect(socket, &QTcpSocket::readyRead, this, &MyThread::readyRead, Qt::ConnectionType::DirectConnection);
        connect(socket, &QTcpSocket::disconnected, this, &MyThread::disconnected, Qt::ConnectionType::DirectConnection);
        qDebug()<<socketDescriptor<<"Client connected";
    
        exec();
    }
    
    void MyThread::readyRead()
    {
        QByteArray data = socket -> readAll();
        qDebug()<<socketDescriptor<<" Data in "<<data;
        socket -> write(data);
    }
    
    void MyThread::disconnected()
    {
        qDebug()<<socketDescriptor<<" Disconnected";
        socket -> deleteLater();
        exit(0);
    }
    

  • Lifetime Qt Champion

    @Christina123 said in Threading for TCP server:

    socket = new QTcpSocket;

    This is wrong as stated in the documentation and in nearly every post about threads. You must create objects in the thread where you use them or move them to this thread with QObject::moveToThread() Also nearly everywhere when a QTcpServer/Socket is used in thread the same question arises - why on hell do you need it?


  • Moderators


  • Lifetime Qt Champion

    @Christina123 said in Threading for TCP server:

    socket = new QTcpSocket;

    This is wrong as stated in the documentation and in nearly every post about threads. You must create objects in the thread where you use them or move them to this thread with QObject::moveToThread() Also nearly everywhere when a QTcpServer/Socket is used in thread the same question arises - why on hell do you need it?



  • Hi, thank you. Declaring the socket in run() solves the problem :)
    I've had another question about threading. I've created two threads in the main QThread sthread, rthread; but when I check their thread ID, I've found that they are identical with each other which is unexpected as I want them to be different.


  • Lifetime Qt Champion

    Hi,

    Just a wild guess, you are checking the thread id outside the run function ?



  • @SGaist Yes, I am afraid I am checking them in the main thread. Is there a way to extract the thread id of them in the main thread?


  • Lifetime Qt Champion

    Thread affinity is a hard concept.

    QThread should be seen as a "thread handler". It has affinity with the thread that created it.

    The actual new thread handles the run method. Whatever you create in that method will have an affinity with the thread handled by QThread.


Log in to reply