QT: socket notifiers cannot be enabled from another thread

22,601

You can only directly interact with the socket from one thread (the thread must have an event loop running - so you should have called exec() on it). If you want to read/write from another thread, you will need to use Signals/Slots.

Connecting a Signal emitted on one thread to a Slot of an object on another thread using the default connection type (Qt::AutoConnection) will automatically ensure a safe thread transfer occurs (using a queued connection). You can explicitly connect a Signal to a Slot using Qt::QueuedConection, but Qt::AutoConnection should work fine.

// Lives on thread 1
class MySocketOwner : public QObject
{
    Q_OBJECT

public:
    MySocketOwner(QObject *Parent = 0)
        : QObject(Parent)
    {
        Socket = new QTcpSocket(this);
        connect(Socket, SIGNAL(readyRead()), this, SLOT(Read()));
    }

    ~MySocketOwner()
    {
        delete Socket;
    }

public slots:
    void Read()
    {
        QByteArray Data = Socket->readAll();
        // Do something with the data
    }

    void Write(QBytrArray Data)
    {
        // Must always be called on thread 1
        Socket->write(Data);
    }

private:
    QTcpSocket *Socket;
};

// Lives on thread 2
class MySocketWriter : public QObject
{
    Q_OBJECT

public:
    MySocketWriter(QObject *Parent = 0)
        : QObject(Parent)
    {
        // If this is on another thread, connection will be queued
        connect(this, SIGNAL(Write(QByteArray)), MySocketOwnerPointer, SLOT(Write(QBytrArray Data)));
        QByteArray Data;
        // Fill with data

        // An event gets put onto thread 1's event queue after this
        emit Write(Data);
    }

signals:
    void Write(QByteArray Data);
};

Like the comments on your question say, you need to think carefully about why you need this behaviour, do you really need to read the same data received by the socket on 2 separate threads?

Share:
22,601
Petr
Author by

Petr

Updated on August 05, 2022

Comments

  • Petr
    Petr almost 2 years

    I have a QTcpSocket and I need to control it - write + read using multiple threads.

    This works fine in QT4 but in QT5 I am getting this error and it seems that only 1 thread has access to socket at a same time. How do I make it possible for a socket to be accessed by multiple threads?

    Basically I want to create 1 thread for reading and 1 thread for writing of data, so that I can asynchronously read and process the data while doing something else in rest of application.

    Note: answer to Qt - Handle QTcpSocket in a new thread doesn't help here, because it describes how to transfer socket from thread 1 to thread 2 and then use it from thread 2 only. I need to use it from both threads.

  • Petr
    Petr over 10 years
    I don't need to read data on 2 threads. I want to read them in 1 thread and write in another one