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. what is the significance of qintptr socket() in QSocketNotifier class?
Qt 6.11 is out! See what's new in the release blog

what is the significance of qintptr socket() in QSocketNotifier class?

Scheduled Pinned Locked Moved Solved General and Desktop
22 Posts 5 Posters 13.1k Views 1 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.
  • Paul ColbyP Paul Colby

    Hi @MokJ,

    How can we get the SocketNotifier of a particular QTcpSocket?

    You should be able to use QAbstractSocket::socketDescriptor() in most cases, eg:

    QTcpSocket * tcpSocket = new QTcpSocket(this);
    // setup the socket.
    
    QSocketNotifier * tcpSocketNotifier =
        new QSocketNotifier(tcpSocket->socketDescriptor(), QSocketNotifier::Read, this);
    

    Cheers.

    M Offline
    M Offline
    MokJ
    wrote on last edited by
    #3

    @Paul-Colby Thanks for responding
    I've done that already but it gives me this notification
    QSocketNotifier: Multiple socket notifiers for same socket 580 and type Write

    1 Reply Last reply
    0
    • Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #4

      That's because QTcpSocket already installed a notifier on it's socket. Otherwise it would not be possible to emit readyRead() and other signals.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      M 1 Reply Last reply
      3
      • Christian EhrlicherC Christian Ehrlicher

        That's because QTcpSocket already installed a notifier on it's socket. Otherwise it would not be possible to emit readyRead() and other signals.

        M Offline
        M Offline
        MokJ
        wrote on last edited by
        #5

        @Christian-Ehrlicher thanks
        So is there a way to get that socket Notifier , created by QTcpSocket itself ?

        1 Reply Last reply
        0
        • Christian EhrlicherC Online
          Christian EhrlicherC Online
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #6

          I don't think so and also don't understand why it should be needed.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          M 1 Reply Last reply
          4
          • Christian EhrlicherC Christian Ehrlicher

            I don't think so and also don't understand why it should be needed.

            M Offline
            M Offline
            MokJ
            wrote on last edited by
            #7

            @Christian-Ehrlicher
            I have created a server client chat program
            I'm connecting multiple clients in one thread and i'm using worker thread for reading and writing. Now in worker thread reading is done smoothly but when it comes to writing (means QTcpSocket->write();) i'm getting notification of 'Socket Notifier cannot be enabled or disabled from other thread.' So I'm trying to do QSocketNotifier::setEnabled(); in that worker thread.
            So any suggestion on that ?

            aha_1980A 1 Reply Last reply
            0
            • M MokJ

              @Christian-Ehrlicher
              I have created a server client chat program
              I'm connecting multiple clients in one thread and i'm using worker thread for reading and writing. Now in worker thread reading is done smoothly but when it comes to writing (means QTcpSocket->write();) i'm getting notification of 'Socket Notifier cannot be enabled or disabled from other thread.' So I'm trying to do QSocketNotifier::setEnabled(); in that worker thread.
              So any suggestion on that ?

              aha_1980A Offline
              aha_1980A Offline
              aha_1980
              Lifetime Qt Champion
              wrote on last edited by aha_1980
              #8

              @MokJ You can use QTcpSocket only from one thread. That means, you have the read and write functions in the same thread.

              From your error description, it seems that is not the case for your program.

              Qt has to stay free or it will die.

              M 1 Reply Last reply
              3
              • aha_1980A aha_1980

                @MokJ You can use QTcpSocket only from one thread. That means, you have the read and write functions in the same thread.

                From your error description, it seems that is not the case for your program.

                M Offline
                M Offline
                MokJ
                wrote on last edited by
                #9

                Thank you @aha_1980
                I'm doing reading and writing in the same thread.
                Problem is, while writing above said notification pops up.
                I'm creating QTcpSocket in different thread which is main thread of the server.

                1 Reply Last reply
                0
                • Christian EhrlicherC Online
                  Christian EhrlicherC Online
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #10

                  And this is exactly what the message tells you. This is not allowed. You can overwrite QTcpServer::incomingConnection() , pass the fd to the other thread and create a QTcpSocket there.

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  M 1 Reply Last reply
                  4
                  • Christian EhrlicherC Christian Ehrlicher

                    And this is exactly what the message tells you. This is not allowed. You can overwrite QTcpServer::incomingConnection() , pass the fd to the other thread and create a QTcpSocket there.

                    M Offline
                    M Offline
                    MokJ
                    wrote on last edited by MokJ
                    #11

                    @Christian-Ehrlicher
                    If I create QTcpSocket in other thread, it means if I have 100 clients I'd be using 100 threads and there comes another problem. I can't have 100 threads. I want to do all the functioning with just 3 threads. Right now I'm creating sockets in main thread where I have over ridden the QTcpServer::incomingConnection(qintptr descriptor);.
                    I have connected readyRead() of the QTcpSocket to myserver's readData() slot.
                    and here in this slot I'm creating a new thread for reading and writing. Is it possible for me to do so without notification ?
                    And what happens when one socket is sending message to another ??

                    kshegunovK 1 Reply Last reply
                    0
                    • M MokJ

                      @Christian-Ehrlicher
                      If I create QTcpSocket in other thread, it means if I have 100 clients I'd be using 100 threads and there comes another problem. I can't have 100 threads. I want to do all the functioning with just 3 threads. Right now I'm creating sockets in main thread where I have over ridden the QTcpServer::incomingConnection(qintptr descriptor);.
                      I have connected readyRead() of the QTcpSocket to myserver's readData() slot.
                      and here in this slot I'm creating a new thread for reading and writing. Is it possible for me to do so without notification ?
                      And what happens when one socket is sending message to another ??

                      kshegunovK Offline
                      kshegunovK Offline
                      kshegunov
                      Moderators
                      wrote on last edited by
                      #12

                      @MokJ said in what is the significance of qintptr socket() in QSocketNotifier class?:

                      If I create QTcpSocket in other thread, it means if I have 100 clients I'd be using 100 threads and there comes another problem.

                      No it doesn't. It means you have to create the socket object in the correct thread - the one that will be doing the reading and writing.

                      I can't have 100 threads. I want to do all the functioning with just 3 threads.

                      Did you adapt my proposed snippet in your other thread?

                      Right now I'm creating sockets in main thread where I have over ridden the QTcpServer::incomingConnection(qintptr descriptor);.

                      Which is wrong. Read the documentation. It's clearly stated that the socket object must be created in the correct thread. As a matter of fact it is the whole purpose of existing for QTcpServer::incomingConnection - it gives you the socket descriptor, so you can create the QTcpSocket object in the correct thread. Creating the socket object in the main thread means you agree that reading and writing will be done from the main thread, thus you get the messages you get - you break that contract and Qt rightfully complains about it!

                      Is it possible for me to do so without notification ?

                      Implement threaded sockets correctly and you won't get the warning.

                      And what happens when one socket is sending message to another ??

                      Eh? I don't understand the question.

                      Read and abide by the Qt Code of Conduct

                      M 1 Reply Last reply
                      5
                      • kshegunovK kshegunov

                        @MokJ said in what is the significance of qintptr socket() in QSocketNotifier class?:

                        If I create QTcpSocket in other thread, it means if I have 100 clients I'd be using 100 threads and there comes another problem.

                        No it doesn't. It means you have to create the socket object in the correct thread - the one that will be doing the reading and writing.

                        I can't have 100 threads. I want to do all the functioning with just 3 threads.

                        Did you adapt my proposed snippet in your other thread?

                        Right now I'm creating sockets in main thread where I have over ridden the QTcpServer::incomingConnection(qintptr descriptor);.

                        Which is wrong. Read the documentation. It's clearly stated that the socket object must be created in the correct thread. As a matter of fact it is the whole purpose of existing for QTcpServer::incomingConnection - it gives you the socket descriptor, so you can create the QTcpSocket object in the correct thread. Creating the socket object in the main thread means you agree that reading and writing will be done from the main thread, thus you get the messages you get - you break that contract and Qt rightfully complains about it!

                        Is it possible for me to do so without notification ?

                        Implement threaded sockets correctly and you won't get the warning.

                        And what happens when one socket is sending message to another ??

                        Eh? I don't understand the question.

                        M Offline
                        M Offline
                        MokJ
                        wrote on last edited by MokJ
                        #13

                        @kshegunov
                        yes I have implemented the worker class according to your proposed snippet , and I'm really thankful for that. But I'm not getting how QMetaObject::invokeMethod is working !

                        And what happens when one socket is sending message to another ??

                        Eh? I don't understand the question.

                        I mean one clientsocket to other clientsocket , just like a chat application . If we're sending a message from one clientsocket to another , the chances of getting the warning abot QSocketNotifier are always there ! I mean I've just stated to clear my basics now so a bit confused about things.

                        kshegunovK 1 Reply Last reply
                        0
                        • M MokJ

                          @kshegunov
                          yes I have implemented the worker class according to your proposed snippet , and I'm really thankful for that. But I'm not getting how QMetaObject::invokeMethod is working !

                          And what happens when one socket is sending message to another ??

                          Eh? I don't understand the question.

                          I mean one clientsocket to other clientsocket , just like a chat application . If we're sending a message from one clientsocket to another , the chances of getting the warning abot QSocketNotifier are always there ! I mean I've just stated to clear my basics now so a bit confused about things.

                          kshegunovK Offline
                          kshegunovK Offline
                          kshegunov
                          Moderators
                          wrote on last edited by
                          #14

                          @MokJ said in what is the significance of qintptr socket() in QSocketNotifier class?:

                          But I'm not getting how QMetaObject::invokeMethod is working !

                          Well, did you read the documentation about it? Qt has the best documentation of a software product I have ever seen in my 10+ years of coding. Many of the topics in the forums could be resolved by simple searches for the examples or the classes' reference documentation.

                          If we're sending a message from one clientsocket to another , the chances of getting the warning abot QSocketNotifier are always there ! I mean I've just stated to clear my basics now so a bit confused about things.

                          If you use signals and slots, you will never get that notification. If you directly call a method from different threads, then you have a race condition and yes you probably will get that warning.

                          Read and abide by the Qt Code of Conduct

                          M 1 Reply Last reply
                          2
                          • kshegunovK kshegunov

                            @MokJ said in what is the significance of qintptr socket() in QSocketNotifier class?:

                            But I'm not getting how QMetaObject::invokeMethod is working !

                            Well, did you read the documentation about it? Qt has the best documentation of a software product I have ever seen in my 10+ years of coding. Many of the topics in the forums could be resolved by simple searches for the examples or the classes' reference documentation.

                            If we're sending a message from one clientsocket to another , the chances of getting the warning abot QSocketNotifier are always there ! I mean I've just stated to clear my basics now so a bit confused about things.

                            If you use signals and slots, you will never get that notification. If you directly call a method from different threads, then you have a race condition and yes you probably will get that warning.

                            M Offline
                            M Offline
                            MokJ
                            wrote on last edited by MokJ
                            #15

                            @kshegunov I've been reading the document so I might come back after a few hours with questions , I've got one more question for now....
                            I've done QByteArray B=socket->readAll(); . Now I have to send this B to the destined socket let say socket123, where should I connect the signal BytesWritten(64) to the appropriate slot?
                            cause till now what I've been doing is, once I get B, the next line of code would be doing QTcpSocket->write(B.toSTDstring().c_str());
                            and maybe that could be the reason of the socket being in the different thread.

                            kshegunovK 1 Reply Last reply
                            0
                            • M MokJ

                              @kshegunov I've been reading the document so I might come back after a few hours with questions , I've got one more question for now....
                              I've done QByteArray B=socket->readAll(); . Now I have to send this B to the destined socket let say socket123, where should I connect the signal BytesWritten(64) to the appropriate slot?
                              cause till now what I've been doing is, once I get B, the next line of code would be doing QTcpSocket->write(B.toSTDstring().c_str());
                              and maybe that could be the reason of the socket being in the different thread.

                              kshegunovK Offline
                              kshegunovK Offline
                              kshegunov
                              Moderators
                              wrote on last edited by
                              #16

                              @MokJ said in what is the significance of qintptr socket() in QSocketNotifier class?:

                              Now I have to send this B to the destined socket let say socket123, where should I connect the signal BytesWritten(64) to the appropriate slot?

                              I don't know what your implementation is, what signals or slots you defined, so I can't say. In any case the connect is ordinarily done wherever it's convenient to you, usually meaning where you hold references to the two objects you're connecting. It is not unusual this to be the constructor of some class.

                              Read and abide by the Qt Code of Conduct

                              M 1 Reply Last reply
                              0
                              • kshegunovK kshegunov

                                @MokJ said in what is the significance of qintptr socket() in QSocketNotifier class?:

                                Now I have to send this B to the destined socket let say socket123, where should I connect the signal BytesWritten(64) to the appropriate slot?

                                I don't know what your implementation is, what signals or slots you defined, so I can't say. In any case the connect is ordinarily done wherever it's convenient to you, usually meaning where you hold references to the two objects you're connecting. It is not unusual this to be the constructor of some class.

                                M Offline
                                M Offline
                                MokJ
                                wrote on last edited by MokJ
                                #17

                                @kshegunov

                                void Worker::readData(){
                                     QTcpSocket *sock=(QTcpSocket*)sender();
                                     QByteArray Message= sock->readAll();
                                     qDebug()<<"Message "<<Message;
                                      for(int i=0;i<clientSocketVector.size();i++){
                                            clientSocketVector[i]->write(Message.toStdString().c_str());
                                        }
                                }
                                

                                if I write like this , I'm getting warning :: QSocketNotifier cannot be enabled or disabled from other thread.

                                kshegunovK 1 Reply Last reply
                                0
                                • M MokJ

                                  @kshegunov

                                  void Worker::readData(){
                                       QTcpSocket *sock=(QTcpSocket*)sender();
                                       QByteArray Message= sock->readAll();
                                       qDebug()<<"Message "<<Message;
                                        for(int i=0;i<clientSocketVector.size();i++){
                                              clientSocketVector[i]->write(Message.toStdString().c_str());
                                          }
                                  }
                                  

                                  if I write like this , I'm getting warning :: QSocketNotifier cannot be enabled or disabled from other thread.

                                  kshegunovK Offline
                                  kshegunovK Offline
                                  kshegunov
                                  Moderators
                                  wrote on last edited by
                                  #18

                                  Yeah, you have a race condition. You need to emit a signal, instead of calling write on all other sockets, and connect that signal to appropriate slots for the objects interested in that data (i.e. the other sockets). That way Qt will handle the thread synchronization for you.

                                  Read and abide by the Qt Code of Conduct

                                  M 1 Reply Last reply
                                  1
                                  • kshegunovK kshegunov

                                    Yeah, you have a race condition. You need to emit a signal, instead of calling write on all other sockets, and connect that signal to appropriate slots for the objects interested in that data (i.e. the other sockets). That way Qt will handle the thread synchronization for you.

                                    M Offline
                                    M Offline
                                    MokJ
                                    wrote on last edited by MokJ
                                    #19

                                    @kshegunov thanks very much for responding

                                    void Worker::readData(){
                                         QTcpSocket *sock=(QTcpSocket*)sender();
                                         QByteArray Message= sock->readAll();
                                         qDebug()<<"Message "<<Message;
                                          for(int i=0;i<clientSocketVector.size();i++){
                                                clientSocket[i]->bytesWritten(64);//Emitted this signal
                                            }
                                    }
                                    void Worker::sendData(qint64){
                                                      for(int i=0;i<clientSocket.size();i++){
                                                                              clientSocket[i]->write(Message.toStdString().c_str());
                                                      }
                                    }    
                                    
                                    //In server class
                                    void server::incomingConnection(qintptr sd)
                                    {
                                     QMetaObject::invokeMethod(worker, [worker, sd] () -> void  {
                                            QTcpSocket * socket = new QTcpSocket(worker);
                                            connect(socket,SIGNAL(bytesWritten(qint64)),worker,SLOT(sendData(qint64)));
                                           if(socket->setSocketDescriptor(sd)){
                                                qDebug()<<"client connected"<<sd;          
                                            }
                                    }
                                    

                                    I tried to replace the signal BytesWritten(); by my own making signal but the warning keeps on popping.

                                    kshegunovK 1 Reply Last reply
                                    0
                                    • M MokJ

                                      @kshegunov thanks very much for responding

                                      void Worker::readData(){
                                           QTcpSocket *sock=(QTcpSocket*)sender();
                                           QByteArray Message= sock->readAll();
                                           qDebug()<<"Message "<<Message;
                                            for(int i=0;i<clientSocketVector.size();i++){
                                                  clientSocket[i]->bytesWritten(64);//Emitted this signal
                                              }
                                      }
                                      void Worker::sendData(qint64){
                                                        for(int i=0;i<clientSocket.size();i++){
                                                                                clientSocket[i]->write(Message.toStdString().c_str());
                                                        }
                                      }    
                                      
                                      //In server class
                                      void server::incomingConnection(qintptr sd)
                                      {
                                       QMetaObject::invokeMethod(worker, [worker, sd] () -> void  {
                                              QTcpSocket * socket = new QTcpSocket(worker);
                                              connect(socket,SIGNAL(bytesWritten(qint64)),worker,SLOT(sendData(qint64)));
                                             if(socket->setSocketDescriptor(sd)){
                                                  qDebug()<<"client connected"<<sd;          
                                              }
                                      }
                                      

                                      I tried to replace the signal BytesWritten(); by my own making signal but the warning keeps on popping.

                                      kshegunovK Offline
                                      kshegunovK Offline
                                      kshegunov
                                      Moderators
                                      wrote on last edited by kshegunov
                                      #20

                                      The slot that is called has to be for an object that's in the same thread for the socket. You need to read on signal-slots and how they're called in multithreaded environment. Just adding a slot anywhere and doing the writing from there won't do.

                                      Ask yourself, when sendData is called, which is the thread of th worker object (instance of the Worker class) and is it the same as for all the objects in the clientSocket array. Surely not, otherwise you wouldn't still get the message, so you must change the design of your program.

                                      Read and abide by the Qt Code of Conduct

                                      M 1 Reply Last reply
                                      2
                                      • kshegunovK kshegunov

                                        The slot that is called has to be for an object that's in the same thread for the socket. You need to read on signal-slots and how they're called in multithreaded environment. Just adding a slot anywhere and doing the writing from there won't do.

                                        Ask yourself, when sendData is called, which is the thread of th worker object (instance of the Worker class) and is it the same as for all the objects in the clientSocket array. Surely not, otherwise you wouldn't still get the message, so you must change the design of your program.

                                        M Offline
                                        M Offline
                                        MokJ
                                        wrote on last edited by MokJ
                                        #21

                                        @kshegunov Thanks very much
                                        You @kshegunov , are a great source of learning, As you suggested about using signals and slots with moveTothread() , I have managed to complete that part and the warning has finally disappeared.
                                        So thanks again @kshegunov , May be we could get a drink , cheers.

                                        kshegunovK 1 Reply Last reply
                                        0
                                        • M MokJ

                                          @kshegunov Thanks very much
                                          You @kshegunov , are a great source of learning, As you suggested about using signals and slots with moveTothread() , I have managed to complete that part and the warning has finally disappeared.
                                          So thanks again @kshegunov , May be we could get a drink , cheers.

                                          kshegunovK Offline
                                          kshegunovK Offline
                                          kshegunov
                                          Moderators
                                          wrote on last edited by
                                          #22

                                          @MokJ said in what is the significance of qintptr socket() in QSocketNotifier class?:

                                          You @kshegunov , are a great source of learning

                                          I should hope so, for my students' sake.

                                          May be we could get a drink , cheers.

                                          Sure, when you're visiting eastern Europe you can poke at me.

                                          Read and abide by the Qt Code of Conduct

                                          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