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

QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread



  • Im writing a Custom ClientNetwork class to connect to a server.
    ClientNetwork inherits QThread class and have a public property "QTcpSocket *clientSocket"
    and i overwrite the run function with a new one which is

     qDebug() << "Client thread started...";
    
        clientSocket = new QTcpSocket();
        clientSocket->connectToHost(hostName, port, QTcpSocket::ReadWrite, QTcpSocket::AnyIPProtocol);
    
        connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readFromSocket()), Qt::DirectConnection);
        connect(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)), Qt::DirectConnection);
        connect(&networkData, SIGNAL(networkWriteToSocket()), clientNetwork, SLOT(writeToSocket()), Qt::AutoConnection);
    
        const int Timeout = 5 * 1000;
    
        if ( !clientSocket->waitForConnected(Timeout) ) {
            qDebug() << "Error: Timeout on connection attempt..";
            emit error(clientSocket->error());
            return;
        }
    
        if ( clientSocket->state() == QAbstractSocket::ConnectedState ) {
            qDebug() << "Client socket successfully connected...";
        }
        else { qDebug() << "Client socketfailed to connected..."; }
        server_connected = 1
    
        exec();
    

    and i connect the write slot "writeToSocket()" to a signal from the main thread through:

        QObject::connect(&networkData, SIGNAL(networkWriteToSocket()), clientNetwork, SLOT(writeToSocket()), Qt::AutoConnection);
    
    

    sockets reads data just fine but when i try to trigger writeToSocket() slot using the signal from the main thread i get "QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread"

    Side Notes : -i tried to write to socket within "readFromSocket()" slot and it works fine (echo client).
    -I have noticed that "writeToSocket()" is called in the main thread not the clientNetwork thread.


  • Qt Champions 2019

    What is 'clientNetwork' and 'networkData'?



  • they r both instants of ClientNetwork class and NetworkData class respectively
    ClientNetwork as i said is a class inherits Qthread and have a publice QTcpSocket property
    and all u need to know about NetworkData that is has a signal called "networkWriteToSocket()" i want to connect to ClientNetwork slot "writeToSocket()" to be able to write to the socket.


  • Qt Champions 2019

    So did you also move ClientNetwork to the newly created thread? See http://doc.qt.io/qt-5/qobject.html#moveToThread

    Otherwise your connect with writeToSocket() will not change the thread since the QThread object itself is in the thread it was created in. It is not automatically moved to the newly created thread.



  • ClientNetwork is the newly created thread if im understanding it right.

    class ClientNetwork : public QThread
    

    how can i move it to the new thread.
    and do u mean the class "ClientNetwork" or its instance "clientNetwork"


  • Qt Champions 2019

    @AmrMaatouk said in QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread:

    how can i move it to the new thread.

    By reading my link...

    ClientNetwork is the newly created thread if im understanding it right.

    That's what I said - it's not the thread. It's an object which creates and handles a thread. That's a completely different thing. And an object lives in the thread where it is created in - in your case in the main thread.
    Please read the QThread docs!



  • @Christian-Ehrlicher
    Actually i have read the docs for both QThread and QObject::MoveToThread
    but i dont see how to implement "moveToThread" properly. I always get a warning: QObject::moveToThread: Current thread (0xd2d850) is not the object's thread (0xd27d30).
    Cannot move to target thread (0xd2d850)"
    im using it this way

    clientNetwork->moveToThread(clientNetwork);
    

    am i doing it correctly ?
    i have tried to put it in many places ( ClientNetwork's Constructor, run(), main.cpp ) and nothing works



  • I managed to solve it by writing

    moveToThread(this);
    

    in the construction of the class.
    thanks


  • Lifetime Qt Champion

    Hi,

    Before anything else read here why adding this moveToThread call is the wrong thing to do.


Log in to reply