title: Qt QTcpSocket() readReady Signal never fires (slot never called) in multithreaded Server applicaton. waitForReadyRead() method works fine
body: <p>I'm writing a threaded TcpServer (each client in its own thread) using QTcpServer and QTcpSocket. The client application works correctly and sends data every 3 seconds but the readReady() signal never fires, meaning my receive_data() function is never called. When using socket->waitForReadyRead() and calling receive_data() by myself everything works fine. Please have a look at the code below, maybe I made some mistake with the moveToThread / connect functionality Qt offers.</p>
  
  <p>Client.h</p>
  
  <pre><code>#ifndef CLIENT_H
  #define CLIENT_H
  
  #include &lt;QThread&gt;
  #include &lt;QTcpSocket&gt;
  #include &lt;QHostAddress&gt;
  #include "PacketDefinitions.h"
  #include "tcpserver.h"
  
  class Client : public QObject
  {
      Q_OBJECT
  public:
      explicit Client(int socket,TcpServer *parent,bool auto_disconnect = true);
      ~Client();
      bool isGameServer(){return is_gameserver;}
      GameServerPacket getGameServerData(){return gameserver;}
      void run();
  private:
      QTcpSocket* client;
      TcpServer *parent_server;
      int socket;
      GameServerPacket gameserver;
      ClientPacket clientdata;
      bool is_gameserver;
      bool auto_disconnect;
      QHostAddress client_ip;
      quint16 client_port;
  signals:
      void disconnected(Client *);
  private slots:
      void remove_from_clientlist();
      void receive_data();
      void display_error(QAbstractSocket::SocketError error);
  };
  
  #endif // CLIENT_H
  </code></pre>
  
  <p>Client.cpp</p>
  
  <pre><code>#include "client.h"
  #include "PacketDefinitions.h"
  #include "time.h"
  #include &lt;iostream&gt;
  
  Client::Client(int _socket, TcpServer *parent,bool _auto_disconnect)
  {
      auto_disconnect = _auto_disconnect;
      parent_server = parent;
      is_gameserver = false;
      socket = _socket;
  }
  
  void Client::run(){ 
      client = new QTcpSocket();
  
      if(client-&gt;setSocketDescriptor(socket) == false){
          std::cout &lt;&lt; client-&gt;errorString().toStdString() &lt;&lt; std::endl;
          remove_from_clientlist();
          return;
      }
  
      connect(client,SIGNAL(disconnected()),this,SLOT(remove_from_clientlist()));
      if(connect(client,SIGNAL(readyRead()),this,SLOT(receive_data()),Qt::DirectConnection) == false) return;
      connect(client,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(display_error(QAbstractSocket::SocketError)));
  
      client_ip = client-&gt;peerAddress();
      client_port = client-&gt;peerPort();
  
      std::cout &lt;&lt; "New incomming connection " &lt;&lt; client-&gt;peerAddress().toString().toStdString() &lt;&lt; ":" &lt;&lt; client-&gt;peerPort() &lt;&lt; std::endl;
  
      //this works fine
  //    while(client-&gt;waitForReadyRead()){
  //        receive_data();
  //    }
  }
  
  void Client::receive_data(){
         QDataStream stream(client);
         stream.setVersion(QDataStream::Qt_5_2);
         quint32 magic; stream &gt;&gt; magic;
         //interpret data
         if(magic == GAMESERVER_MAGIC){
             is_gameserver = true;
             gameserver.Read(stream);
             gameserver.port = client_port;
             gameserver.ip = client_ip;
             time(&amp;(gameserver.last_update));
             parent_server-&gt;add_server(gameserver.ip.toString(),gameserver);
             std::cout &lt;&lt; "GameServer " &lt;&lt; gameserver.name &lt;&lt; " registerd" &lt;&lt; std::endl;
         }else if(magic == CLIENT_MAGIC){
             is_gameserver = false;
             clientdata.Read(stream);
             //get nearby servers
             GameServerListPacket server_list = parent_server-&gt;getServerList(clientdata);
             QDataStream outstream(client);
             server_list.Write(outstream);
             std::cout &lt;&lt; "Sending ServerList(" &lt;&lt; server_list.server_count &lt;&lt; ") to " &lt;&lt; client-&gt;peerAddress().toString().toStdString() &lt;&lt; std::endl;
             if(auto_disconnect){
                 //client-&gt;flush();
                 client-&gt;waitForBytesWritten();
             }
  
         }else{
             std::cout &lt;&lt; "Unknown package " &lt;&lt; magic &lt;&lt; std::endl;
         }
  
         //not enough data read, somthing is wrong, just for debugging
         if(client-&gt;bytesAvailable()&gt; 0)  std::cout &lt;&lt; "BytesAvailable " &lt;&lt; client-&gt;bytesAvailable() &lt;&lt; std::endl;
  
      if(auto_disconnect) remove_from_clientlist();//close the connection once the serverlist was deployed
  }
  </code></pre>
  
  <p>In the TcpServer.cpp add_client() is called when newConnection() was emitted by the QTcpServer:</p>
  
  <pre><code>void TcpServer::add_client(){
      while(server-&gt;hasPendingConnections()){
          QTcpSocket *socket = 0;
          if(thread_pool.size() &lt; max_connections &amp;&amp; (socket = server-&gt;nextPendingConnection())){
              QThread *thread = new QThread();
              Client * client = new Client(socket-&gt;socketDescriptor(),this,auto_disconnect);
              client-&gt;moveToThread(thread);
              client-&gt;run();
              thread-&gt;start();
              connect(client,SIGNAL(disconnected(Client*)),this,SLOT(remove_client(Client*)));
              WRITELOCK(thread_pool.insert(client,thread));
          }
      }
  }
  </code></pre>
  
  <p>the order calling client->run() and thread->start() doesn't seem to matter. Some time ago the code (not this exact code) worked fine but I can't remember what I changed that made it fail. Any help is appreciated!</p>
  
  <p>Thanks in advance
  Fabian</p>
  
  <p>Edit 1:</p>
  
  <p>I derived from QTcpServer and reimplemented void incomingConnection(qintptr socketDescriptor) which works fine. I dont use QThreadPool, its just a QMap and remove_client(Client*) closes the QTcpSocket and stops the thread and removes it from the map. Everything works fine on linux, on windows I get the following error: QSocketNotifier: socket notifiers cannot be disabled from another thread ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread....</p>
  
  <p><img src="https://i.stack.imgur.com/RJlKT.png" alt="Screenshot"></p>
  
  <p>Caused by this remove_client(Client*)</p>
  
  <pre><code>void TcpServer::remove_client(Client *client){
      //disconnect(client,SIGNAL(disconnected(Client*)),this,SLOT(remove_client(Client*)));
      lock.lockForWrite();    
      QMap&lt;Client*,QThread*&gt;::iterator itr = thread_pool.find(client);
      if(itr != thread_pool.end()){
          //delete itr.key(); causes the problem on windows
          itr.value()-&gt;quit();
          itr.value()-&gt;wait();
          delete itr.value();
          thread_pool.erase(itr);
      }
      lock.unlock();
  }
  </code></pre>
  
  <p>Where and how should I free the Client object? If i'd use QThreadPool theres no way to iterate through the clients in case i want to send a message to more than one client. I could use a list/map holding only the Client* but then QThreadPool might delete them for me right before i want to access it. Any suggestions?</p>