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. QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread

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

Scheduled Pinned Locked Moved Unsolved General and Desktop
qthreadqtcpserver
23 Posts 3 Posters 6.4k Views
  • 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.
  • S SGaist
    1 Apr 2019, 20:42

    What is your exact use of QSerialPort ?

    D Offline
    D Offline
    Dooham
    wrote on 1 Apr 2019, 21:10 last edited by
    #14

    @SGaist I read the continuous message that a device (a Pixhawk). Every thing that I receive a package of message ( the serial port send me package of message) in form of QByteArray I send it to a client that can decode them

    1 Reply Last reply
    0
    • D Dooham
      1 Apr 2019, 19:09

      @CP71 I think that is not neccesary,because of the function incomingConnection. When I see this Code I had a similar doubt, but this function is a virtual function of QtcpServer that is called when a newConnection Signal appears. In this code,I just edit the function a bit.
      Maybe the trouble would be that I didnt called the write function from the run, and this could be problematic. In a while, I will try to rewrite the code un order to call the function that write the message from the run

      D Offline
      D Offline
      Dooham
      wrote on 2 Apr 2019, 07:32 last edited by
      #15

      @Dooham That didn't work, I dont know what is the trouble, I have seen that there are two different QThread ID, and that is probably the cause of the issue:
      0_1554190211682_3c2ed1b3-b00e-4493-9839-8182529d1966-image.png
      As you can see, I got the adress of the Thread that I generate with the incomingConnection but, in some point I create an Object that its parent is other QThread.
      I dont know what to do.

      1 Reply Last reply
      0
      • D Dooham
        1 Apr 2019, 19:09

        @CP71 I think that is not neccesary,because of the function incomingConnection. When I see this Code I had a similar doubt, but this function is a virtual function of QtcpServer that is called when a newConnection Signal appears. In this code,I just edit the function a bit.
        Maybe the trouble would be that I didnt called the write function from the run, and this could be problematic. In a while, I will try to rewrite the code un order to call the function that write the message from the run

        C Offline
        C Offline
        CP71
        wrote on 2 Apr 2019, 08:34 last edited by CP71 4 Feb 2019, 08:36
        #16

        @Dooham
        I think you don't call addPendingConnection or it seems so

        0_1554194144567_013b5385-d81d-4dd1-be58-d950d072f8e1-image.png

        1 Reply Last reply
        0
        • D Dooham
          1 Apr 2019, 09:52

          Hello,
          I am having this trouble since two days ago and I am not sure how solve this error.
          I made a code for a server that can handle multiple connections, my goal is to read in the server messages from a device in the serialPort, send this messages to all the clients connected to my server and, from the clients can send message to the device. To do this, I saw that I need programming a Thread that can handle the multiple connections.
          I made this code:

          myserver.cpp

          #include "myserver.h"
          
          MyServer::MyServer(QObject *parent) : QTcpServer (parent)
          {
          
          }
          
          void MyServer::startServer()
          {
              if(!this->listen(QHostAddress::Any, 9999)){
          qDebug()<<"Server not started";
              }else {
          qDebug()<<"Server listening";
              }
          }
          
          void MyServer::startSerialPort()
          {
             mipuerto2 = new MySerialPort;
             connect(mipuerto2, SIGNAL(msgChanged()), this, SLOT(getMens()));
             mipuerto2->openSerialPort();
          }
          
          void MyServer::getMens()
          {
              arr2=mipuerto2->getMensaje();
          
              emit mensChanged(&arr2);
          }
          
          void MyServer::sendMens(QByteArray *arraySend)
          {
          mipuerto2->writeMsg(*arraySend);
          }
          
          
          void MyServer::incomingConnection(int socketDescriptor)
          {
          
          qDebug()<<socketDescriptor<<"Connecting... ";
          MyThread *thread=new MyThread(socketDescriptor, this);
          connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
          connect(this, SIGNAL(mensChanged(QByteArray * )), thread, SLOT(getMsg(QByteArray *)));
          connect(thread, SIGNAL(mensajeEnviar(QByteArray * )), this,SLOT(sendMens(QByteArray * )));
          thread->start();
          
          }
          

          mythread.cpp

          #include "mythread.h"
          
          MyThread::MyThread(int ID, QObject *parent) : QThread(parent)
          {
              this->socketDescriptor=ID;
          
          }
          
          void MyThread::run()
          {
          //thread start here
              qDebug()<<socketDescriptor<< " Starting thread";
              socket = new QTcpSocket();
              if(!socket->setSocketDescriptor(this->socketDescriptor)){
                  emit error(socket->error());
          
              }
          
              connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
              connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()), Qt::DirectConnection);
          
              qDebug() << socketDescriptor<< " Client Connect";
          
          
          
              exec();
          }
          
          void MyThread::readyRead()
          {
          
              msgSend="";
             // socket->waitForReadyRead(100);
              msgSend=socket->readAll();
          
                  qDebug()<<msgSend.toHex();
          emit mensajeEnviar(&msgSend);
          }
          
          void MyThread::disconnected()
          {
              qDebug() << socketDescriptor<< " Disconnected";
          
              socket->deleteLater();
          
              exit(0);
          }
          
          void MyThread::getMsg(QByteArray * array)
          {
          
              socket->write(*array);
              socket->waitForBytesWritten(3000);
          
          }
          

          So everytime that, the serial port read a new group of messages, emit a signal to send them.
          With this code, I can read the messages from the client and send message (I haven't probe with more connections yet), but when I read I get this error in the server console:

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

          This error appears every time that a new messages arrives to the server from the serial port. Does anyone know what I can do to solve it?
          Thanks.

          D Offline
          D Offline
          Dooham
          wrote on 2 Apr 2019, 08:40 last edited by
          #17

          @Dooham @CP71 @SGaist Finally I could "solve" the trouble that I had. I had to create other class that has the QTcpSocket, and create that class inside the run function of the thread as a local variable. However I found some trouble with the write method, I dont know how to solve it. The trouble is that dont read the client (with the previous code I could read, the messaged from the client). This is my code:

          myserver.cpp

          MyServer::MyServer(QObject *parent) : QTcpServer (parent)
          {
          
          }
          
          void MyServer::startServer()
          {
              if(!this->listen(QHostAddress::Any, 9999)){
          qDebug()<<"Server not started";
              }else {
          qDebug()<<"Server listening";
              }
          }
          
          void MyServer::startSerialPort()
          {
             mipuerto2 = new MySerialPort;
            connect(mipuerto2, SIGNAL(msgChanged(QByteArray*)), this, SLOT(getMens(QByteArray*)));
             mipuerto2->openSerialPort();
          }
          
          void MyServer::getMens(QByteArray*array)
          {
          
          
          
              emit mensChanged(array);
          }
          
          void MyServer::sendMens(QByteArray *arraySend)
          {
          mipuerto2->writeMsg(*arraySend);
          }
          
          
          void MyServer::incomingConnection(int socketDescriptor)
          {
          
          qDebug()<<socketDescriptor<<"Connecting... ";
          MyThread *thread=new MyThread(socketDescriptor, this);
          
          qDebug()<<thread;
          connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
          connect(this, SIGNAL(mensChanged(QByteArray * )), thread, SLOT(getMsg(QByteArray *)));
          connect(thread, SIGNAL(mensajeEnviar(QByteArray * )), this,SLOT(sendMens(QByteArray * )));
          
          
          
          thread->start();
          
          }
          
          

          myserialport.cpp

          #include "myserialport.h"
          #include <QObject>
          #include <QtSerialPort/QSerialPort>
          #include <QDebug>
          
          
          MySerialPort::MySerialPort()
          {
              serial = new QSerialPort(this);
              data= "";
          
              connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
              openSerialPort();
          
          }
          
          void MySerialPort::openSerialPort()
          {
              serial->setPortName("COM4");
              //serial->setBaudRate(QSerialPort::Baud9600);
              serial->setBaudRate(QSerialPort::Baud115200);
              serial->setDataBits(QSerialPort::Data8);
              serial->setParity(QSerialPort::NoParity);
              serial->setStopBits(QSerialPort::OneStop);
              serial->setFlowControl(QSerialPort::NoFlowControl);
              serial->open(QIODevice::ReadWrite);
          
          
          }
          
          void MySerialPort::closeSerialPort()
          {
              if(serial->isOpen()){
                  serial->close();
              }
          }
          
          void MySerialPort::readData()
          {
          
             data = serial->readAll();
              dataAux=data.toHex();
              emit msgChanged(&data);
          
          }
          
          QByteArray MySerialPort::getMensaje()
          {
              return data;
          }
          
          void MySerialPort::writeMsg(QByteArray datos)
          {
          
              serial->write(datos);
          
          }
          
          

          mythread.cpp

          #include "mythread.h"
          #include "mysocket.h"
          MyThread::MyThread(int ID, QObject *parent) : QThread(parent)
          {
              this->socketDescriptor=ID;
          
          
          }
          
          void MyThread::run()
          {
              qDebug()<<socketDescriptor<< " Starting thread";
              MySocket socket2(this->socketDescriptor);
              //Revisar mas tarde
              /*if(!socket2.setSocketDescriptor(this->socketDescriptor)){
                  emit error(socket->error());
          
              }*/
          
              /*connect(socket2, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);*/
          
          
              connect(this, SIGNAL(mensajeRecibido(QByteArray*)), &socket2, SLOT(getMsg(QByteArray*)));
              connect(&socket2, SIGNAL(disconnected()), this, SLOT(disconnected()));
              connect(&socket2, SIGNAL(mensajeEnviarSocket(QByteArray*)), this, SLOT(readyRead(QByteArray*)));
              qDebug() << socketDescriptor<< " Client Connect";
          
          
          
              exec();
          }
          
          void MyThread::readyRead(QByteArray*arraySent)
          {
          
          
              qDebug()<<arraySent->toHex();
              emit mensajeEnviar(arraySent);
          }
          
          void MyThread::disconnected()
          {
              qDebug() << socketDescriptor<< " Disconnected";
          
              //socket->deleteLater();
          
              exit(0);
          }
          
          void MyThread::getMsg(QByteArray * array)
          {
              emit mensajeRecibido(array);
          
          
          }
          

          mysocket.cpp (This is the new class)

          #include "mysocket.h"
          
          MySocket::MySocket(int socketDescriptor)
          {
          socket= new QTcpSocket;
          socket->setSocketDescriptor(socketDescriptor);
          connect(this, SIGNAL(disconnected()), this, SLOT(desconexion()));
          connect(this, SIGNAL(readyRead()), this, SLOT(leerMsg()));
          qDebug()<<"Hola";
          }
          
          void MySocket::leerMsg()
          {
              msgSend="";
              // socket->waitForReadyRead(100);
              msgSend=socket->readAll();
          
              qDebug()<<msgSend.toHex();
              emit mensajeEnviarSocket(&msgSend);
          }
          
          void MySocket::desconexion()
          {
             socket->deleteLater();
          }
          
          void MySocket::getMsg(QByteArray *array)
          {
          
              arr=*array;
              //qDebug()<<arr;
             // qDebug()<<"server a thread";
              socket->write(arr);
              socket->flush();
              socket->waitForBytesWritten(3000);
          }
          
          

          mysocket.h

          #ifndef MYSOCKET_H
          #define MYSOCKET_H
          
          #include <QObject>
          #include <QTcpSocket>
          
          class MySocket:public QTcpSocket
          {
              Q_OBJECT
          public:
              MySocket(int socketDescriptor);
          signals:
              void mensajeEnviarSocket(QByteArray *arraySend);
          
          public slots:
              void leerMsg();
              void desconexion();
              void getMsg(QByteArray *array);
          private:
              QTcpSocket *socket;
              QByteArray arr;
              QByteArray msgSend;
          };
          
          #endif // MYSOCKET_H
          

          With this code, I can read the serial port and sending to the client without troubles (I also tried with the telnet command and two connections, and this could with them). But I can read the messages sent. Another trouble that I saw, is that, when I disconect the client, in the server appears the following error: QAbstractSocket::waitForBytesWritten() is not allowed in UnconnectedState

          Does anyone knows how I can solve this issues?
          Thanks for your help.

          D 1 Reply Last reply 2 Apr 2019, 09:01
          0
          • D Dooham
            2 Apr 2019, 08:40

            @Dooham @CP71 @SGaist Finally I could "solve" the trouble that I had. I had to create other class that has the QTcpSocket, and create that class inside the run function of the thread as a local variable. However I found some trouble with the write method, I dont know how to solve it. The trouble is that dont read the client (with the previous code I could read, the messaged from the client). This is my code:

            myserver.cpp

            MyServer::MyServer(QObject *parent) : QTcpServer (parent)
            {
            
            }
            
            void MyServer::startServer()
            {
                if(!this->listen(QHostAddress::Any, 9999)){
            qDebug()<<"Server not started";
                }else {
            qDebug()<<"Server listening";
                }
            }
            
            void MyServer::startSerialPort()
            {
               mipuerto2 = new MySerialPort;
              connect(mipuerto2, SIGNAL(msgChanged(QByteArray*)), this, SLOT(getMens(QByteArray*)));
               mipuerto2->openSerialPort();
            }
            
            void MyServer::getMens(QByteArray*array)
            {
            
            
            
                emit mensChanged(array);
            }
            
            void MyServer::sendMens(QByteArray *arraySend)
            {
            mipuerto2->writeMsg(*arraySend);
            }
            
            
            void MyServer::incomingConnection(int socketDescriptor)
            {
            
            qDebug()<<socketDescriptor<<"Connecting... ";
            MyThread *thread=new MyThread(socketDescriptor, this);
            
            qDebug()<<thread;
            connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
            connect(this, SIGNAL(mensChanged(QByteArray * )), thread, SLOT(getMsg(QByteArray *)));
            connect(thread, SIGNAL(mensajeEnviar(QByteArray * )), this,SLOT(sendMens(QByteArray * )));
            
            
            
            thread->start();
            
            }
            
            

            myserialport.cpp

            #include "myserialport.h"
            #include <QObject>
            #include <QtSerialPort/QSerialPort>
            #include <QDebug>
            
            
            MySerialPort::MySerialPort()
            {
                serial = new QSerialPort(this);
                data= "";
            
                connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
                openSerialPort();
            
            }
            
            void MySerialPort::openSerialPort()
            {
                serial->setPortName("COM4");
                //serial->setBaudRate(QSerialPort::Baud9600);
                serial->setBaudRate(QSerialPort::Baud115200);
                serial->setDataBits(QSerialPort::Data8);
                serial->setParity(QSerialPort::NoParity);
                serial->setStopBits(QSerialPort::OneStop);
                serial->setFlowControl(QSerialPort::NoFlowControl);
                serial->open(QIODevice::ReadWrite);
            
            
            }
            
            void MySerialPort::closeSerialPort()
            {
                if(serial->isOpen()){
                    serial->close();
                }
            }
            
            void MySerialPort::readData()
            {
            
               data = serial->readAll();
                dataAux=data.toHex();
                emit msgChanged(&data);
            
            }
            
            QByteArray MySerialPort::getMensaje()
            {
                return data;
            }
            
            void MySerialPort::writeMsg(QByteArray datos)
            {
            
                serial->write(datos);
            
            }
            
            

            mythread.cpp

            #include "mythread.h"
            #include "mysocket.h"
            MyThread::MyThread(int ID, QObject *parent) : QThread(parent)
            {
                this->socketDescriptor=ID;
            
            
            }
            
            void MyThread::run()
            {
                qDebug()<<socketDescriptor<< " Starting thread";
                MySocket socket2(this->socketDescriptor);
                //Revisar mas tarde
                /*if(!socket2.setSocketDescriptor(this->socketDescriptor)){
                    emit error(socket->error());
            
                }*/
            
                /*connect(socket2, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);*/
            
            
                connect(this, SIGNAL(mensajeRecibido(QByteArray*)), &socket2, SLOT(getMsg(QByteArray*)));
                connect(&socket2, SIGNAL(disconnected()), this, SLOT(disconnected()));
                connect(&socket2, SIGNAL(mensajeEnviarSocket(QByteArray*)), this, SLOT(readyRead(QByteArray*)));
                qDebug() << socketDescriptor<< " Client Connect";
            
            
            
                exec();
            }
            
            void MyThread::readyRead(QByteArray*arraySent)
            {
            
            
                qDebug()<<arraySent->toHex();
                emit mensajeEnviar(arraySent);
            }
            
            void MyThread::disconnected()
            {
                qDebug() << socketDescriptor<< " Disconnected";
            
                //socket->deleteLater();
            
                exit(0);
            }
            
            void MyThread::getMsg(QByteArray * array)
            {
                emit mensajeRecibido(array);
            
            
            }
            

            mysocket.cpp (This is the new class)

            #include "mysocket.h"
            
            MySocket::MySocket(int socketDescriptor)
            {
            socket= new QTcpSocket;
            socket->setSocketDescriptor(socketDescriptor);
            connect(this, SIGNAL(disconnected()), this, SLOT(desconexion()));
            connect(this, SIGNAL(readyRead()), this, SLOT(leerMsg()));
            qDebug()<<"Hola";
            }
            
            void MySocket::leerMsg()
            {
                msgSend="";
                // socket->waitForReadyRead(100);
                msgSend=socket->readAll();
            
                qDebug()<<msgSend.toHex();
                emit mensajeEnviarSocket(&msgSend);
            }
            
            void MySocket::desconexion()
            {
               socket->deleteLater();
            }
            
            void MySocket::getMsg(QByteArray *array)
            {
            
                arr=*array;
                //qDebug()<<arr;
               // qDebug()<<"server a thread";
                socket->write(arr);
                socket->flush();
                socket->waitForBytesWritten(3000);
            }
            
            

            mysocket.h

            #ifndef MYSOCKET_H
            #define MYSOCKET_H
            
            #include <QObject>
            #include <QTcpSocket>
            
            class MySocket:public QTcpSocket
            {
                Q_OBJECT
            public:
                MySocket(int socketDescriptor);
            signals:
                void mensajeEnviarSocket(QByteArray *arraySend);
            
            public slots:
                void leerMsg();
                void desconexion();
                void getMsg(QByteArray *array);
            private:
                QTcpSocket *socket;
                QByteArray arr;
                QByteArray msgSend;
            };
            
            #endif // MYSOCKET_H
            

            With this code, I can read the serial port and sending to the client without troubles (I also tried with the telnet command and two connections, and this could with them). But I can read the messages sent. Another trouble that I saw, is that, when I disconect the client, in the server appears the following error: QAbstractSocket::waitForBytesWritten() is not allowed in UnconnectedState

            Does anyone knows how I can solve this issues?
            Thanks for your help.

            D Offline
            D Offline
            Dooham
            wrote on 2 Apr 2019, 09:01 last edited by
            #18

            @Dooham I have solved the trouble with waitforBytesWritten with the function: waitforConnected() that return true if is connected so, I just read if the socket is connected. But I cant read yet.

            C 2 Replies Last reply 2 Apr 2019, 12:41
            1
            • D Dooham
              2 Apr 2019, 09:01

              @Dooham I have solved the trouble with waitforBytesWritten with the function: waitforConnected() that return true if is connected so, I just read if the socket is connected. But I cant read yet.

              C Offline
              C Offline
              CP71
              wrote on 2 Apr 2019, 12:41 last edited by
              #19

              @Dooham
              Hi,
              I quickly watch your code.
              I see a thing that is a bit dangerous or I think so, you emit a pointer and not a copy of data without thread synchronization, don’t you?

              D 1 Reply Last reply 2 Apr 2019, 14:29
              1
              • D Dooham
                2 Apr 2019, 09:01

                @Dooham I have solved the trouble with waitforBytesWritten with the function: waitforConnected() that return true if is connected so, I just read if the socket is connected. But I cant read yet.

                C Offline
                C Offline
                CP71
                wrote on 2 Apr 2019, 13:03 last edited by
                #20

                @Dooham
                And more,
                I think you must call addPendingConnection in your incomingConnection

                void MyServer::incomingConnection(int socketDescriptor)
                {

                …

                addPendingConnection( thread→GetQTcpSocketPointer() )

                thread->start();

                }

                1 Reply Last reply
                1
                • C CP71
                  2 Apr 2019, 12:41

                  @Dooham
                  Hi,
                  I quickly watch your code.
                  I see a thing that is a bit dangerous or I think so, you emit a pointer and not a copy of data without thread synchronization, don’t you?

                  D Offline
                  D Offline
                  Dooham
                  wrote on 2 Apr 2019, 14:29 last edited by
                  #21

                  @CP71 I dont know if this is dangerous or not, but it is easy to change, I think. So I will change it later to pass a QByteArray and not a QByteArray pointer. Related to pendingConnection, I don know if this is necessary or not. I am just going to have a few connection. I proved ths code with three clients and I didnt have troubles. With the exception that I cant send message to the serialport, but is a problem that dont depend of the number of connections. However I saw that the trouble is that the socket dont emit the signal readyRead in the socket of the server when I receive a message from a client.

                  C 1 Reply Last reply 2 Apr 2019, 17:28
                  1
                  • D Dooham
                    2 Apr 2019, 14:29

                    @CP71 I dont know if this is dangerous or not, but it is easy to change, I think. So I will change it later to pass a QByteArray and not a QByteArray pointer. Related to pendingConnection, I don know if this is necessary or not. I am just going to have a few connection. I proved ths code with three clients and I didnt have troubles. With the exception that I cant send message to the serialport, but is a problem that dont depend of the number of connections. However I saw that the trouble is that the socket dont emit the signal readyRead in the socket of the server when I receive a message from a client.

                    C Offline
                    C Offline
                    CP71
                    wrote on 2 Apr 2019, 17:28 last edited by
                    #22

                    @Dooham
                    Ok,
                    When we have some problems we say, “the computer has always reason”, well almost always.
                    I’m joking ;)

                    I already done a TCP Server but I took another road and I hadn't got special problems, so now I haven’t ideas. :(

                    If I can, I suggest you to solve one problem at a time, I would start at the end, as per QtcpSocket, to try to understand why readyRead seems not working I should check the following checks:

                    • Check with Wireshark or other tools if TCP packets arrive to your device
                    • Check by debug text info about QTcpSocket that you have created (e.g. IP of the client)

                    Then climb up to TcpServer.

                    Sorry

                    D 1 Reply Last reply 2 Apr 2019, 17:36
                    1
                    • C CP71
                      2 Apr 2019, 17:28

                      @Dooham
                      Ok,
                      When we have some problems we say, “the computer has always reason”, well almost always.
                      I’m joking ;)

                      I already done a TCP Server but I took another road and I hadn't got special problems, so now I haven’t ideas. :(

                      If I can, I suggest you to solve one problem at a time, I would start at the end, as per QtcpSocket, to try to understand why readyRead seems not working I should check the following checks:

                      • Check with Wireshark or other tools if TCP packets arrive to your device
                      • Check by debug text info about QTcpSocket that you have created (e.g. IP of the client)

                      Then climb up to TcpServer.

                      Sorry

                      D Offline
                      D Offline
                      Dooham
                      wrote on 2 Apr 2019, 17:36 last edited by
                      #23

                      @CP71 Dont worry, you are helpful. I will tried to find the trouble, I know that must be in my Code of the server, because in the first Code that I published in this thread I could do It. And in a simpler Code for just one connection server-client It also worked.

                      1 Reply Last reply
                      1

                      23/23

                      2 Apr 2019, 17:36

                      • Login

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