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. QTcpServer with QThreadPool, for long term connections.
Forum Updated to NodeBB v4.3 + New Features

QTcpServer with QThreadPool, for long term connections.

Scheduled Pinned Locked Moved General and Desktop
4 Posts 3 Posters 9.5k 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.
  • rootshellR Offline
    rootshellR Offline
    rootshell
    wrote on last edited by
    #1

    Hello,

    Was wondering if anyone could point me in the right direction...

    Working with sockets and trying to make a multi-threaded TCP server. Anyone that has done this for a large traffic application knows that one thread per-socket is a BAD idea, too many connections and the application crashes.

    So I was looking at QThreadPool and QRunnable, but I cannot for the life of me find an example where the socket is a long term connection, or maybe I am just miss-understanding QRunnable.

    General concept:

    Client connects, the server kicks off a new QRunnable, and the run() function is called.

    @void MyRunnable::run()
    { //thread starts here

    socket = new QTcpSocket();
    if(!socket->setSocketDescriptor(this->socketDescriptor))
    {
        emit error(socket->error());
        return;
    }
    connect(socket,SIGNAL(readyRead()),this,SLOT(readyRead()),Qt::DirectConnection);
    connect(socket,SIGNAL(disconnected()),this,SLOT(disconnected()),Qt::DirectConnection);
    

    ...//somehow keep the socket alive even though the QRunnable is done
    ...//for a thread we would put exec(); here
    }

    void MyRunnable::readyRead()
    {
    //read data from the socket and send a response
    }

    void MyRunnable:: disconnected ()
    {
    //make sure the socket is deleted
    }@

    My main problem (or rather concern) is that QRunnable is not the same as a thread, but rather seemed to be a fire and forget kind of class...

    Perhaps I am looking at this wrong?

    Perhaps all the signal and slots should take place on one thread, and all the socket IO should be called as a QRunnable, in other words, connect all the signals and slots on the main thread, and then each time you want to read or write to and from the socket you make a new QRunnable sub-class for that.

    Anyways I come from the C# / VB.Net world and have read a lot about IO completion ports:
    http://en.wikipedia.org/wiki/Input/output_completion_port

    Can anyone point me in the right direction or tell me if I am just generally confused :)

    Certifications: CISSP, MCITP, MCSE, MCSA, BA, AA, AG, CST, CNST, Linux+, Security+, Server+, Network+, A+, iNet+

    Languages: C++, C#, VB, Python, Java

    1 Reply Last reply
    1
    • D Offline
      D Offline
      dangelog
      wrote on last edited by
      #2

      You can't use QRunnable here because you need an event loop running.
      Moreover, you can't pass QTcpSockets around between threads. They can only be used from the thread they're created. You have to subclass QTcpServer and pass the descriptor to the thread you want to handle the socket, and create the QTcpSocket there. You do this by overriding QTcpServer::incomingConnection.

      So:

      • create your own thread pool of N threads (i.e. N QThreads)
      • create N worker objects, one per thread, and move each one into a different thread of the pool
      • start the event loops in those threads (i.e. QThread::start on each one)
      • in the "main" thread create the server, put it into listening and start the event loop
      • when a new connection is received, incomingConnection is called: take the fd and dispatch it to a worker object (using any policy you like)
      • the worker object receives the descriptor and creates the QTcpSocket object and calls setSocketDescriptor on it, set up the signal/slot connections etc.

      The "passing descriptor" mechanism itself is quite interesting because it can be easily implemented through a custom event containing the descriptor. You just need to create the event and post it to the right worker object. Qt will provide the thread-safe queue.

      Software Engineer
      KDAB (UK) Ltd., a KDAB Group company

      1 Reply Last reply
      1
      • rootshellR Offline
        rootshellR Offline
        rootshell
        wrote on last edited by
        #3

        [quote author="peppe" date="1302915836"]You can't use QRunnable here because you need an event loop running. Moreover, you can't pass QTcpSockets around between threads. They can only be used from the thread they're created. You have to subclass QTcpServer and pass the descriptor to the thread you want to handle the socket, and create the QTcpSocket there. You do this by overriding QTcpServer::incomingConnection. So: * create your own thread pool of N threads (i.e. N QThreads) * create N worker objects, one per thread, and move each one into a different thread of the pool * start the event loops in those threads (i.e. QThread::start on each one) * in the "main" thread create the server, put it into listening and start the event loop * when a new connection is received, incomingConnection is called: take the fd and dispatch it to a worker object (using any policy you like) * the worker object receives the descriptor and creates the QTcpSocket object and calls setSocketDescriptor on it, set up the signal/slot connections etc. The "passing descriptor" mechanism itself is quite interesting because it can be easily implemented through a custom event containing the descriptor. You just need to create the event and post it to the right worker object. Qt will provide the thread-safe queue.[/quote]

        Thanks, I will give it a shot!

        Know of any examples out on the net?

        Certifications: CISSP, MCITP, MCSE, MCSA, BA, AA, AG, CST, CNST, Linux+, Security+, Server+, Network+, A+, iNet+

        Languages: C++, C#, VB, Python, Java

        1 Reply Last reply
        0
        • D Offline
          D Offline
          danger89
          wrote on last edited by
          #4

          I also would like to see some example of this, please.

          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