Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QT QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
Forum Updated to NodeBB v4.3 + New Features

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

Scheduled Pinned Locked Moved Unsolved General and Desktop
25 Posts 4 Posters 9.0k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    JadeN001
    wrote on last edited by kshegunov
    #1

    hello,i am getting this notification when i a using readAll or write() function of QTcpSocket.
    here is my code for client implemantation.
    conversation.cpp

    #include "conversation.h"
    
    QTextStream cin(stdin);
    
    QString text;
    conversation::conversation(QTcpSocket *s1,QObject *parent): QObject(parent)
    {
       C_socket=s1;
    }
    conversation::conversation(){
    
    }
    
    void conversation::readdata(QTcpSocket *s ){
    
        qDebug()<<"in readline..";
        qDebug()<< s;
        s->waitForReadyRead(10000);
      while(s->bytesAvailable()){
        qDebug()<<"reading...."<<s->readAll();
       }
    
         // do{
         qDebug()<<"reading complete";
         if(!s->bytesAvailable()){
             emit stringtoRead(s);
         }
    
    }
    void conversation::writedata(QTcpSocket *s ){
        while(true){
        qDebug()<<"to write somthing";
        text=cin.readLine();
        qDebug()<<"in producer :"<<" "<<text;
        if(s->write(text.toStdString().c_str()))
        {
            qDebug()<<"has been written..";
        }
        }
    }
    

    client.cpp

    #include "client.h"
    #include<QtConcurrent/qtconcurrentrun.h>
    client::client(QObject *parent):QObject(parent){
    }
    void client::test(){
       //connect
       m_sock=new QTcpSocket();
        connect(m_sock,SIGNAL(connected()),this,SLOT(connected()));
        connect(m_sock,SIGNAL(disconnected()),this,SLOT(disconnected()));
        qDebug()<<"connecting...";
        m_sock->connectToHost("127.0.0.1",100);
        if(!m_sock->waitForConnected(1000)){
           qDebug()<<"somthing bad happen "<<m_sock->errorString();
        }
    
    }
    void client::connected(){
        qDebug()<<"connected";
    
        connect(&c,&conversation::stringtoRead,&c,&conversation::readdata);
        QFuture<void>f1=QtConcurrent::run(&this->c,&conversation::writedata,m_sock);
        QFuture<void>f2=QtConcurrent::run(&this->c,&conversation::readdata,m_sock);
    
    }
    

    [Added code tags ~kshegunov]

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Take a look at the Threaded Fortune Server example to see how to manage QTcpSocket in a multithreaded environment.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      J 1 Reply Last reply
      2
      • SGaistS SGaist

        Hi,

        Take a look at the Threaded Fortune Server example to see how to manage QTcpSocket in a multithreaded environment.

        J Offline
        J Offline
        JadeN001
        wrote on last edited by JadeN001
        #3

        @SGaist thanks , i have gone through it. But my purpose differs from the Fortune server.
        here in my code of client i'm using different approach then Fortune code. What I can't really understand is where exactly i'm not following QT's format of QObject and QThread.
        My code works fine but I'm getting this notification every time when it writes something using write().
        qDebug()<<"to write somthing";
        text=cin.readLine();
        qDebug()<<"in producer :"<<" "<<text;
        if(m_sock->write(text.toStdString().c_str()))// HERE THAT NOTIFICATION APPEARS
        {
        qDebug()<<"has been written..";
        }

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          You are passing your QTcpSocket object around different threads. The threaded fortune server shows that the sockets are created in each new thread and handled by them.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          J 1 Reply Last reply
          2
          • SGaistS SGaist

            You are passing your QTcpSocket object around different threads. The threaded fortune server shows that the sockets are created in each new thread and handled by them.

            J Offline
            J Offline
            JadeN001
            wrote on last edited by
            #5

            @SGaist the problem is that i have to pass the socket value (m_sock) as parameter to another class (conversation class) so that it can know which socket needs to implement the Write and Read function.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              The thing is that you pass a socket to the constructor, then you want to pass a socket to these function and you want to do reading and writing on the same socket from different threads.

              From the looks of it, you could leverage Qt's asynchronous nature before starting to use so many threads.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              J 1 Reply Last reply
              1
              • SGaistS SGaist

                The thing is that you pass a socket to the constructor, then you want to pass a socket to these function and you want to do reading and writing on the same socket from different threads.

                From the looks of it, you could leverage Qt's asynchronous nature before starting to use so many threads.

                J Offline
                J Offline
                JadeN001
                wrote on last edited by
                #7

                @SGaist here i made changes in my program, but QT fires that warning everytime write() function is called.

                #include "client.h"
                QTextStream cin(stdin);
                QString text;
                client::client(QObject *parent):QObject(parent)
                {

                }
                void client::startconnection(){
                connect(client_socket,SIGNAL(connected()),this,SLOT(connection()));
                connect(client_socket,SIGNAL(disconnected()),this,SLOT(disconnection()));
                connect(this,SIGNAL(stringtoRead()),this,SLOT(readdata()));
                client_socket->connectToHost("127.0.0.1",100);
                if(!client_socket->waitForConnected(1000)){
                qDebug()<<"Somthing is bad in connection..";
                }
                ForCommunication();
                }

                void client::connection(){
                qDebug()<<"connection is successfull";
                }

                void client::ForCommunication(){
                qDebug()<<"in communication class..";

                QFuture<void>f2=QtConcurrent::run(this,&client::readdata);
                QFuture<void>f1=QtConcurrent::run(this,&client::writedata);
                

                }
                void client::disconnection(){
                qDebug()<<"disconnected..";
                }
                void client::writedata(){
                while(true)
                {
                qDebug()<<"to write somthing";
                text=cin.readLine();
                qDebug()<<"in producer :"<<" "<<text;
                client_socket->write(text.toStdString().c_str());
                qDebug()<<"has been written..";

                }
                

                }

                void client::readdata(){
                qDebug()<<"in readline..";
                client_socket->waitForReadyRead(10000);
                while(client_socket->bytesAvailable()){
                qDebug()<<"reading...."<<client_socket->readAll();
                qDebug()<<"reading complete";
                }

                if(!client_socket->bytesAvailable()){
                emit stringtoRead();
                }
                }

                jsulmJ 1 Reply Last reply
                0
                • J JadeN001

                  @SGaist here i made changes in my program, but QT fires that warning everytime write() function is called.

                  #include "client.h"
                  QTextStream cin(stdin);
                  QString text;
                  client::client(QObject *parent):QObject(parent)
                  {

                  }
                  void client::startconnection(){
                  connect(client_socket,SIGNAL(connected()),this,SLOT(connection()));
                  connect(client_socket,SIGNAL(disconnected()),this,SLOT(disconnection()));
                  connect(this,SIGNAL(stringtoRead()),this,SLOT(readdata()));
                  client_socket->connectToHost("127.0.0.1",100);
                  if(!client_socket->waitForConnected(1000)){
                  qDebug()<<"Somthing is bad in connection..";
                  }
                  ForCommunication();
                  }

                  void client::connection(){
                  qDebug()<<"connection is successfull";
                  }

                  void client::ForCommunication(){
                  qDebug()<<"in communication class..";

                  QFuture<void>f2=QtConcurrent::run(this,&client::readdata);
                  QFuture<void>f1=QtConcurrent::run(this,&client::writedata);
                  

                  }
                  void client::disconnection(){
                  qDebug()<<"disconnected..";
                  }
                  void client::writedata(){
                  while(true)
                  {
                  qDebug()<<"to write somthing";
                  text=cin.readLine();
                  qDebug()<<"in producer :"<<" "<<text;
                  client_socket->write(text.toStdString().c_str());
                  qDebug()<<"has been written..";

                  }
                  

                  }

                  void client::readdata(){
                  qDebug()<<"in readline..";
                  client_socket->waitForReadyRead(10000);
                  while(client_socket->bytesAvailable()){
                  qDebug()<<"reading...."<<client_socket->readAll();
                  qDebug()<<"reading complete";
                  }

                  if(!client_socket->bytesAvailable()){
                  emit stringtoRead();
                  }
                  }

                  jsulmJ Offline
                  jsulmJ Offline
                  jsulm
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

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

                  client_socket

                  where do you create it?

                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                  J 1 Reply Last reply
                  1
                  • jsulmJ jsulm

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

                    client_socket

                    where do you create it?

                    J Offline
                    J Offline
                    JadeN001
                    wrote on last edited by JadeN001
                    #9

                    @jsulm In client.h file.

                    0_1524635085296_clientH.png
                    Before i put this line start connection function but still i was getting same error.so i put it on header file to check does it make any change or not and i did not get any changes

                    jsulmJ 1 Reply Last reply
                    0
                    • J JadeN001

                      @jsulm In client.h file.

                      0_1524635085296_clientH.png
                      Before i put this line start connection function but still i was getting same error.so i put it on header file to check does it make any change or not and i did not get any changes

                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @JadeN001 You create the socket in a different thread than the two threads where it is used with QtConcurrent::run.
                      So, you still use same socket in different threads.
                      Why do you use threads at all? As @SGaist suggested you can simply use assynchronous Qt APIs...

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      J 1 Reply Last reply
                      1
                      • jsulmJ jsulm

                        @JadeN001 You create the socket in a different thread than the two threads where it is used with QtConcurrent::run.
                        So, you still use same socket in different threads.
                        Why do you use threads at all? As @SGaist suggested you can simply use assynchronous Qt APIs...

                        J Offline
                        J Offline
                        JadeN001
                        wrote on last edited by JadeN001
                        #11

                        @jsulm thanks
                        I'm confused with the phrase "different thread" .Am I supposed to create new QTcpSocket for each thread!! and if so, where should it be declared?
                        I'll go through the assynchronus API . but Is it possible to get rid of this warning by using thread concept !

                        jsulmJ 1 Reply Last reply
                        0
                        • J JadeN001

                          @jsulm thanks
                          I'm confused with the phrase "different thread" .Am I supposed to create new QTcpSocket for each thread!! and if so, where should it be declared?
                          I'll go through the assynchronus API . but Is it possible to get rid of this warning by using thread concept !

                          jsulmJ Offline
                          jsulmJ Offline
                          jsulm
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @JadeN001 To get rid of this message you have to do multi-threading in the correct way.
                          But the question is: why do you need threads? With asynchronous Qt APIs there is usually no need for threads for such use cases. Why do you think you need threads?

                          https://forum.qt.io/topic/113070/qt-code-of-conduct

                          J 1 Reply Last reply
                          1
                          • J.HilkJ Offline
                            J.HilkJ Offline
                            J.Hilk
                            Moderators
                            wrote on last edited by J.Hilk
                            #13

                            Hier a little helper, code is untested, so you'll may have to modify /bugfix it:

                            asynchronus and threaded.

                            //main.cpp
                            
                            #include <QApplication>
                            #include <QThread>
                            #include "client.h"
                            
                            int main(int argc, char *argv[])
                            {
                                QApplication a(argc, argv);
                            
                                QThread *thread = new QThread ();
                                client *m_client = new client();
                                m_client->moveToThread(thread);
                                QObject::connect(thread, &QThread::started, m_client, &client::startconnection);
                                QObject::connect(thread, &QThread::finished, m_client, &client::deleteLater);
                                QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
                                thread->start();
                            
                                return a.exec();
                            }
                            
                            
                            #include "client.h"
                            
                            client::client(QObject *parent):QObject(parent)
                            {
                            
                            }
                            void client::startconnection()
                            {
                                QTcpSocket client_socket = new QTcpSocket(this);
                                
                                connect(client_socket, &QTcpSocket::bytesWritten, this, &client::BytesWritten);
                                connect(client_socket, &QTcpSocket::readyRead, this, &client::ReadyRead);
                                
                                connect(client_socket,SIGNAL(connected()),this,SLOT(connection()));
                                connect(client_socket,SIGNAL(disconnected()),this,SLOT(disconnection()));
                                
                                client_socket->connectToHost("127.0.0.1",100);
                            }
                            
                            void client::BytesWritten(const quint64 &bytes){
                                qDebug() << bytes << "Bytes written";
                            }
                            
                            void client::ReadyRead(){
                                qDebug() << Q_FUNC_INFO << client_socket->readAll();
                            }
                            
                            void client::connection(){
                                qDebug()<<"connection is successfull, now write test data";
                                writedata("TestString");
                            }
                            
                            void client::disconnection(){
                                qDebug()<<"disconnected..";
                            }
                            void client::writedata(const QString &str){
                                qDebug()<<"to write somthing";
                                client_socket->write(str.c_str());
                            }
                            

                            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                            Q: What's that?
                            A: It's blue light.
                            Q: What does it do?
                            A: It turns blue.

                            J 2 Replies Last reply
                            0
                            • jsulmJ jsulm

                              @JadeN001 To get rid of this message you have to do multi-threading in the correct way.
                              But the question is: why do you need threads? With asynchronous Qt APIs there is usually no need for threads for such use cases. Why do you think you need threads?

                              J Offline
                              J Offline
                              JadeN001
                              wrote on last edited by
                              #14

                              @jsulm I'm trying to create a chat application kind of program without using QWidgets .
                              So I need to make program work parallelly in aspect of sending and receiving messages without being blocked. I tried it without using QThread and QConcurrent (meaning I used signals and SLOTs only).
                              So in that code , the readyRead() gets called only after I write something. It means even if there's data to read , I can't get that data till I write something first.
                              So what I want here is when a client is sending some data, the other client should not get blocked into writing mode and it should be able to read the data and display. So the problem that i am facing is ,when readyRead() is called data gets stored into buffer and after write() function completed it display whole messages which was in buffer.

                              1 Reply Last reply
                              0
                              • J.HilkJ J.Hilk

                                Hier a little helper, code is untested, so you'll may have to modify /bugfix it:

                                asynchronus and threaded.

                                //main.cpp
                                
                                #include <QApplication>
                                #include <QThread>
                                #include "client.h"
                                
                                int main(int argc, char *argv[])
                                {
                                    QApplication a(argc, argv);
                                
                                    QThread *thread = new QThread ();
                                    client *m_client = new client();
                                    m_client->moveToThread(thread);
                                    QObject::connect(thread, &QThread::started, m_client, &client::startconnection);
                                    QObject::connect(thread, &QThread::finished, m_client, &client::deleteLater);
                                    QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
                                    thread->start();
                                
                                    return a.exec();
                                }
                                
                                
                                #include "client.h"
                                
                                client::client(QObject *parent):QObject(parent)
                                {
                                
                                }
                                void client::startconnection()
                                {
                                    QTcpSocket client_socket = new QTcpSocket(this);
                                    
                                    connect(client_socket, &QTcpSocket::bytesWritten, this, &client::BytesWritten);
                                    connect(client_socket, &QTcpSocket::readyRead, this, &client::ReadyRead);
                                    
                                    connect(client_socket,SIGNAL(connected()),this,SLOT(connection()));
                                    connect(client_socket,SIGNAL(disconnected()),this,SLOT(disconnection()));
                                    
                                    client_socket->connectToHost("127.0.0.1",100);
                                }
                                
                                void client::BytesWritten(const quint64 &bytes){
                                    qDebug() << bytes << "Bytes written";
                                }
                                
                                void client::ReadyRead(){
                                    qDebug() << Q_FUNC_INFO << client_socket->readAll();
                                }
                                
                                void client::connection(){
                                    qDebug()<<"connection is successfull, now write test data";
                                    writedata("TestString");
                                }
                                
                                void client::disconnection(){
                                    qDebug()<<"disconnected..";
                                }
                                void client::writedata(const QString &str){
                                    qDebug()<<"to write somthing";
                                    client_socket->write(str.c_str());
                                }
                                
                                J Offline
                                J Offline
                                JadeN001
                                wrote on last edited by
                                #15

                                @J.Hilk thanks , I'll definitely look into it. Thanks again.

                                1 Reply Last reply
                                0
                                • J.HilkJ J.Hilk

                                  Hier a little helper, code is untested, so you'll may have to modify /bugfix it:

                                  asynchronus and threaded.

                                  //main.cpp
                                  
                                  #include <QApplication>
                                  #include <QThread>
                                  #include "client.h"
                                  
                                  int main(int argc, char *argv[])
                                  {
                                      QApplication a(argc, argv);
                                  
                                      QThread *thread = new QThread ();
                                      client *m_client = new client();
                                      m_client->moveToThread(thread);
                                      QObject::connect(thread, &QThread::started, m_client, &client::startconnection);
                                      QObject::connect(thread, &QThread::finished, m_client, &client::deleteLater);
                                      QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
                                      thread->start();
                                  
                                      return a.exec();
                                  }
                                  
                                  
                                  #include "client.h"
                                  
                                  client::client(QObject *parent):QObject(parent)
                                  {
                                  
                                  }
                                  void client::startconnection()
                                  {
                                      QTcpSocket client_socket = new QTcpSocket(this);
                                      
                                      connect(client_socket, &QTcpSocket::bytesWritten, this, &client::BytesWritten);
                                      connect(client_socket, &QTcpSocket::readyRead, this, &client::ReadyRead);
                                      
                                      connect(client_socket,SIGNAL(connected()),this,SLOT(connection()));
                                      connect(client_socket,SIGNAL(disconnected()),this,SLOT(disconnection()));
                                      
                                      client_socket->connectToHost("127.0.0.1",100);
                                  }
                                  
                                  void client::BytesWritten(const quint64 &bytes){
                                      qDebug() << bytes << "Bytes written";
                                  }
                                  
                                  void client::ReadyRead(){
                                      qDebug() << Q_FUNC_INFO << client_socket->readAll();
                                  }
                                  
                                  void client::connection(){
                                      qDebug()<<"connection is successfull, now write test data";
                                      writedata("TestString");
                                  }
                                  
                                  void client::disconnection(){
                                      qDebug()<<"disconnected..";
                                  }
                                  void client::writedata(const QString &str){
                                      qDebug()<<"to write somthing";
                                      client_socket->write(str.c_str());
                                  }
                                  
                                  J Offline
                                  J Offline
                                  JadeN001
                                  wrote on last edited by
                                  #16

                                  @J.Hilk thnaks , after doing some changes to this code , I no longer see those warnings in client code...but client doesn't read untill I write something(using cin.readline() function). Is there a way through which client doesn't wait to write something and reads the message from other client, in short it doesn't get blocked in writing.

                                  J.HilkJ 1 Reply Last reply
                                  0
                                  • J JadeN001

                                    @J.Hilk thnaks , after doing some changes to this code , I no longer see those warnings in client code...but client doesn't read untill I write something(using cin.readline() function). Is there a way through which client doesn't wait to write something and reads the message from other client, in short it doesn't get blocked in writing.

                                    J.HilkJ Offline
                                    J.HilkJ Offline
                                    J.Hilk
                                    Moderators
                                    wrote on last edited by
                                    #17

                                    @JadeN001 ready read is emitted as soon as data is available at the socket.

                                    The fact that you only get data when you write something has nothing to do with qt, but with the server you connect to.

                                    Change the server you have, so that he sends without beeing triggered first. A Timer for example.


                                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                    Q: What's that?
                                    A: It's blue light.
                                    Q: What does it do?
                                    A: It turns blue.

                                    J 1 Reply Last reply
                                    1
                                    • SGaistS Offline
                                      SGaistS Offline
                                      SGaist
                                      Lifetime Qt Champion
                                      wrote on last edited by
                                      #18

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

                                      text=cin.readLine();

                                      Isn't that a blocking operation ? If so, the event loop is blocked until you get something from stdin.

                                      Interested in AI ? www.idiap.ch
                                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                      J 1 Reply Last reply
                                      1
                                      • J.HilkJ J.Hilk

                                        @JadeN001 ready read is emitted as soon as data is available at the socket.

                                        The fact that you only get data when you write something has nothing to do with qt, but with the server you connect to.

                                        Change the server you have, so that he sends without beeing triggered first. A Timer for example.

                                        J Offline
                                        J Offline
                                        JadeN001
                                        wrote on last edited by
                                        #19

                                        @J.Hilk My server is just sending message when it arrives from client.i think at client side, i have to change the logic of calling write() function only when if there is no data in buffer for reading..I have tried to use bytesavailable().but it is not working.Do you have any idea about it?

                                        1 Reply Last reply
                                        0
                                        • SGaistS SGaist

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

                                          text=cin.readLine();

                                          Isn't that a blocking operation ? If so, the event loop is blocked until you get something from stdin.

                                          J Offline
                                          J Offline
                                          JadeN001
                                          wrote on last edited by
                                          #20

                                          @SGaist yes , that too is causing trouble. can you suggest any nonblocking userinput method? I'm really stuck at this point , SocketNotifier warning and this cin.readLine().

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved