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. Threaded SSLServer using QSslSocket With bidirectional communication (avoid "QSocketNotifier: Socket notifiers cannot ...")
Forum Updated to NodeBB v4.3 + New Features

Threaded SSLServer using QSslSocket With bidirectional communication (avoid "QSocketNotifier: Socket notifiers cannot ...")

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 2 Posters 2.0k 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.
  • R Offline
    R Offline
    Ritchie
    wrote on last edited by
    #1

    Hi,

    I have written a SSL Server with threaded socket handling, which works fine
    until I have only a one way communication.

    Since I try to add a bidirectional communication, I get the "QSocketNotifier: Socket notifiers cannot ..." message.

    The reason for this I mostly understand, because of the socket was created in other thread and can not be modified by
    other thread.

    But how do I have to create a socket, which can handled in other thread with read and write to connected client ?
    Each thread can give different answers to the connected clients.

    Best regards
    R.

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

      Hi,

      So you are moving your sockets around in different threads ? Can you explain your architecture in more details ?

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

      1 Reply Last reply
      0
      • R Offline
        R Offline
        Ritchie
        wrote on last edited by
        #3

        @SGaist
        I have a base window which will handle the SSLServer listen function

          m_SSLServer->setSslProtocol(QSsl::TlsV1_2);
        
            if (!m_SSLServer->listen(QHostAddress::Any,sTCPIPPort.toInt(&ok, 10)))
               ...
        

        Based on the signal "incomingConnection"

           void incomingConnection(qintptr socketDescriptor) override final;
        

        a thread with the actual socketdescriptor will created by

           QThread* SSL_thread = new QThread;
            TCPThread *m_task = new TCPThread(socketDescriptor,&m_SQLDatabase);   // Create thread object for transmission
            m_task->moveToThread(SSL_thread);
        
            connect( SSL_thread, SIGNAL(started()), m_task, SLOT(doWork()) );
            connect( m_task, SIGNAL(WorkFinished()), SSL_thread, SLOT(quit()) );
        
            //automatically delete thread and task object when work is done:
            connect(SSL_thread, SIGNAL(finished()), m_task, SLOT(deleteLater()));	// Setup stuff by closing the thread
            connect(SSL_thread, SIGNAL(finished()), SSL_thread, SLOT(deleteLater()) );
        //    connect(SSL_thread, SIGNAL(TCPThreadError(QString,int)),
        //                        this, SLOT(ShowTCPThreadError(QString,int)));		// Message queue in matter of errors
            SSL_thread->start();
        

        The class will install the following signals and handle the communication over the signals of the class.

        {
            m_socketDescriptor=socketDS;							// Copy the tcp/iP descriptor locally
            m_SQLDatabase = SQLDatabase;                             // get the connection from the main process
            m_StateMachineState=NoConnection;
            m_blockSize = 0;                                        // No byte received
        
            m_sslSocket.setPrivateKey(ApplicationPath+ "../config/" + sPrivatSSLKey);
            m_sslSocket.setLocalCertificate(ApplicationPath+ "../config/" + sLocalSSLCertificate);
            m_sslSocket.setProtocol(QSsl::TlsV1_2);
            m_sslSocket.ignoreSslErrors();
        
            if ( m_sslSocket.setSocketDescriptor(m_socketDescriptor) == false)	// Connect the socket to the
                {
                m_LastErrorMessage=m_sslSocket.errorString() + tr(": reported from TCP thread");
                emit TCPThreadError(m_LastErrorMessage,1);
                }
        
            connect(&m_sslSocket,SIGNAL(disconnected(void)), this,SLOT(disconnected(void)));
            connect(&m_sslSocket,SIGNAL(hostFound(void)), this,SLOT(hostFound(void)));
            connect(&m_sslSocket,SIGNAL(connected(void)), this,SLOT(connected(void)));
            typedef void (QSslSocket::* sslErrorsSignal)(const QList<QSslError> &);
            connect(&m_sslSocket, static_cast<sslErrorsSignal>(&QSslSocket::sslErrors),this, &TCPThread::SSLError);
            connect(&m_sslSocket,SIGNAL(readyRead(void)), this,SLOT(readyRead(void)));
            connect(&m_sslSocket,SIGNAL(aboutToClose(void)), this,SLOT(aboutToClose(void)));
            connect(&m_sslSocket,SIGNAL(bytesWritten(qint64)), this,SLOT(bytesWritten(qint64)));
            m_sslSocket.startServerEncryption();
        }
        

        It works as long, as the client is only sending information.

        But I would to send results back to the client like

            QByteArray					*block;										// Stream Buffer
        
            block	= new QByteArray;
            QDataStream			outStream(block, QIODevice::ReadWrite);         // just for write only
            outStream.setVersion(QDataStream::Qt_5_4);							// Set the version of stream
        
            switch( m_ParameterType )
                {
                case			LastPosition:                 // error in command
                                    break;
                case			CustomerData:                 // get data from the clients car
                                    if ( sendCustomerData(inStream) )
                                        {
                                        outStream <<  "OK";
                                        }
                                    else
                                        {
                                        outStream << "NK";
                                        }
                                    m_sslSocket.write(*block);											// Send data to the Server
                                    m_sslSocket.flush();                                               // send out the data to the server now
                                    m_StateMachineState=CommunicationFinish;
                                    break;
                case			RecordData:                   // write the information into the database
                                    break;
                }
        
              delete  block;
        

        And during the function "m_sslSocket.write(*block);" I will get the message "QSocketNotifier: Socket notifiers cannot ..."

        And hint to solve this ?

        Best regards
        R.

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

          Looks like your socket is a member variable of TCPThread which will not be moved to the new thread. You should give it a parent so when calling move to thread it's properly moved along.

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

          1 Reply Last reply
          2
          • R Offline
            R Offline
            Ritchie
            wrote on last edited by
            #5

            @SGaist
            Hi,

            maybe is misunderstood your advise.

            I change the parent link of the thread:

                m_task->setParent(0);              << ---add Clear parent information (I guess useless)
                m_task->moveToThread(SSL_thread);
            

            I change the object type from object to object pointer and create the object during creation of the thread.

            class TCPThread : public QThread
            {
            	Q_OBJECT
            
            public:
                TCPThread(int, QSqlDatabase *);                                         // Create a thread object
            	~TCPThread();
            ...
            private:
                QSslSocket      *m_sslSocket;                                            // TCP Socket Pointer
            ...
            };
            
            TCPThread::TCPThread(int socketDS,QSqlDatabase *SQLDatabase)
            {
                m_sslSocket = new QSslSocket();
            ...
            } 
            

            But I still get the message of the "QSocketNotifier".

            What did I misunderstood ?

            Best regards
            R.

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

              It's m_sslSocket that you should give a parent to (i.e. add this in the parenthesis).

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

              1 Reply Last reply
              0
              • R Offline
                R Offline
                Ritchie
                wrote on last edited by Ritchie
                #7

                @SGaist
                Hi,

                I changed it to

                this->m_sslSocket->
                

                Edit: I checked as well, only one thread is running.

                Same result.
                Best regards
                R.

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

                  That's not what I suggested.

                  Here:

                  m_sslSocket = new QSslSocket(this);
                  

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

                  1 Reply Last reply
                  1
                  • R Offline
                    R Offline
                    Ritchie
                    wrote on last edited by
                    #9

                    Thanks. That solve this problem.
                    Best regards
                    R.

                    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