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. [SOLVED] Multithreaded QSslSocket Server Problem

[SOLVED] Multithreaded QSslSocket Server Problem

Scheduled Pinned Locked Moved General and Desktop
qsslsocketqtcpserverqtcpsocketqthreadqsslsslqsocketnotifier
3 Posts 1 Posters 3.1k 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 Offline
    S Offline
    SebastianS
    wrote on last edited by SebastianS
    #1

    Hey guys,

    I have a problem regarding a multithreaded QTcpServer. Here is the server code:

    PDSSLServer::PDSSLServer(QWidget *parent) :
        QMainWindow(parent)
    {
        server = new QTcpServer(this);
        connect(server, SIGNAL(newConnection()), this, SLOT(newConnection()));
        connect(server, SIGNAL(acceptError(QAbstractSocket::SocketError)), this,     SLOT(serverError(QAbstractSocket::SocketError)));
    }
    
    void PDSSLServer::newConnection()
    {
        qDebug() << "PDSSLServer::newConnection()";
        while(server->hasPendingConnections())
        {
            incomingConnection(server->nextPendingConnection()->socketDescriptor());
        }
    }
    
    void PDSSLServer::incomingConnection(int socketDescriptor)
    {
        qDebug("PDSSLServer::incomingConnection(%d)", socketDescriptor);
    
        ClientThread *clThread = new ClientThread(socketDescriptor, SERVERCERTIFICATE_FILE);
        connect(clThread, SIGNAL(finished()), this, SLOT(threadClosed()));
        connect(clThread, SIGNAL(sqlError(QString)), this, SLOT(showSqlError(QString)));
        clThread->start();
    }
    

    I reduced the code due to readability. Here is the client code:

    ClientThread::ClientThread(int socketDescr, QString serverCert, QObject *parent): QThread(parent)
    {
        qDebug() << "ClientThread::ClientThread(" <<socketDescr << "," << serverCert <<"," <<parent <<"):" <<parent;
    
        socketDescriptor = socketDescr;
        this->serverCert = serverCert;
        blockSize = 0;
    
        connect(this, SIGNAL(acceptSocket()), this, SLOT(createSocket()));
        emit acceptSocket();
    }
    
    void ClientThread::run()
    {
        qDebug() << "ClientThread::run()"; 
    
        exec();
    }
    
    void ClientThread::createSocket()
    {
        //New Connection
        qDebug() << "New Thread with socket-ID: " << socketDescriptor;
    
        socket = new QSslSocket;
    
        if(!socket)
        {
            qWarning("not enough memory to create new QSslSocket!");
            emit error(socket->error());
            exit(1);
        }
        socket->setProtocol(QSsl::SslV3);
    
        connectSocketSignals();
    
        socket->setSocketOption(QAbstractSocket::KeepAliveOption, true );
    
        if(!socket->setSocketDescriptor(socketDescriptor))
        {
            qWarning("could not set socket descriptor!");
            socket->deleteLater();
            exit(2);
        }
    
        startServerEncryption();
    
        qDebug() << "Client connected" << socketDescriptor;
    

    The reason why I emit the signal acceptSocket() in the constructor is that I have to communicate with the socket from another thread and therefore this thread has to be the owner of the socket which makes it impossible to create it in the run() method.

    Here finally comes the problem which making me nuts. Everything is doing fine until I get to the point if(!socket->setSocketDescriptor(socketDescriptor)). I get an error message telling "QSocketNotifier: Multiple socket notifiers for same socket 748 and type Read". I know what it means but how can I resolve that issue? In my opinion its the correct way to set up a 'QSslSocket'. I've read a huge amount of posts here but nothing seems to work. Please help me out!

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SebastianS
      wrote on last edited by
      #2

      Ok I finally sovled the issue. Sometimes it helps to read the documentation in detail...

      In QTcpServer documentation for method incomingConnection(qintptr socketDescriptor) it says the following:

      "Note: If you want to handle an incoming connection as a new QTcpSocket object in another thread you have to pass the socketDescriptor to the other thread and create the QTcpSocket object there and use its setSocketDescriptor() method."

      So what I simply had to do is the following:

      #ifndef THREADEDTCPSERVER_H
      #define THREADEDTCPSERVER_H
      
      #include <QObject>
      #include <QTcpServer>
      
      class ThreadedTcpServer : public QTcpServer
      {
          Q_OBJECT
      public:
          ThreadedTcpServer();
          ~ThreadedTcpServer();
      
      signals:
          void newIncomingConnection(qintptr socketDescriptor);
      
      private:
          void incomingConnection(qintptr socketDescriptor);
      };
      
      #endif // THREADEDTCPSERVER_H
      
      #include "threadedtcpserver.h"
      
      ThreadedTcpServer::ThreadedTcpServer()
      {
      
      }
      
      ThreadedTcpServer::~ThreadedTcpServer()
      {
      
      }
      
      void ThreadedTcpServer::incomingConnection(qintptr socketDescriptor)
      {
          newIncomingConnection(socketDescriptor);
      }
      

      Then connect the Signal newIncomingConnection(socketDescriptor) to the PDSSLServer::incomingConnection(int socketDescriptor) method and it works! Maybe it helps somebody with the same issue.

      1 Reply Last reply
      0
      • S Offline
        S Offline
        SebastianS
        wrote on last edited by
        #3

        Hi,

        since I am convinced that somebody else will also have similar problems I wrote a tutorial how to create a multithreaded server:

        https://five-s.de/en/how-to-create-a-multithreaded-server-in-qt

        Best regards

        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