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. QTcpSocket does not detect disconnect when created from worker thread
Forum Updated to NodeBB v4.3 + New Features

QTcpSocket does not detect disconnect when created from worker thread

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 4 Posters 2.2k Views 2 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.
  • M Offline
    M Offline
    Milo
    wrote on last edited by
    #1

    I am trying to use a QTcpSocket from a worker thread like in this example http://doc.qt.io/qt-5/qtnetwork-blockingfortuneclient-example.html

    The socket connects properly.

    However it fails to detects when the host disconnects. So the thread remains stuck in the loop.

    If i create the socket in the main thread, it detects the disconnection properly.

    class ClientThread : public QThread
    {
    Q_OBJECT

    public:
        ClientThread(QObject *parent = 0) {};
        ~ClientThread() {};
    
        void run() Q_DECL_OVERRIDE;
    

    };

    void ClientThread::run()
    {
    QTcpSocket socket;
    socket.connectToHost(SERVER, PORT);

    if (socket.waitForConnected(TIMEOUT)) 
    {
        // sleep as long as connected
        while(socket.state() == QAbstractSocket::SocketState::ConnectedState)
        {
            QThread::msleep(10);
        }
    
        // should exit here when host disconnects
        QThread::msleep(10);
    }
    

    }

    // from Main thread I call this
    client_thread.start();

    Why is that?

    K kshegunovK 2 Replies Last reply
    0
    • M Milo

      I am trying to use a QTcpSocket from a worker thread like in this example http://doc.qt.io/qt-5/qtnetwork-blockingfortuneclient-example.html

      The socket connects properly.

      However it fails to detects when the host disconnects. So the thread remains stuck in the loop.

      If i create the socket in the main thread, it detects the disconnection properly.

      class ClientThread : public QThread
      {
      Q_OBJECT

      public:
          ClientThread(QObject *parent = 0) {};
          ~ClientThread() {};
      
          void run() Q_DECL_OVERRIDE;
      

      };

      void ClientThread::run()
      {
      QTcpSocket socket;
      socket.connectToHost(SERVER, PORT);

      if (socket.waitForConnected(TIMEOUT)) 
      {
          // sleep as long as connected
          while(socket.state() == QAbstractSocket::SocketState::ConnectedState)
          {
              QThread::msleep(10);
          }
      
          // should exit here when host disconnects
          QThread::msleep(10);
      }
      

      }

      // from Main thread I call this
      client_thread.start();

      Why is that?

      K Offline
      K Offline
      koahnig
      wrote on last edited by
      #2

      @Milo
      Did you check if it detects the dsiconnect when in main thread?

      AFAIK there might be a long timeout until the state is changed. I am checking the write to the host does not send all data respectively no data.

      Vote the answer(s) that helped you to solve your issue(s)

      1 Reply Last reply
      0
      • M Offline
        M Offline
        Milo
        wrote on last edited by
        #3

        Yes I did.

        if I run the following on the main thread, I exit the loop right when I close the server.

        QTcpSocket socket;
        socket.connectToHost(SERVER, PORT);

        if (socket.waitForConnected(TIMEOUT))
        {
        // sleep as long as connected
        while(socket.state() == QAbstractSocket::SocketState::ConnectedState)
        {
        QThread::msleep(10);
        }

        // should exit here when host disconnects
        QThread::msleep(10);
        

        }

        }

        1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by VRonin
          #4

          from client_thread.start(); I see the thread is created on the stack, are you sure it does not go out of scope? QThread::start does not block the main thread.

          Could you show us the method where you call start() or try making client_thread a pointer to ClientThread and do

          client_thread=new ClientThread;
          connect(client_thread,&ClientThread::finished,client_thread,&ClientThread::deleteLater);
          client_thread->start();
          

          P.S.
          When reimplementing any QObject you should always call the base class constructor to avoid breaking Qt parent-child system
          ClientThread(QObject *parent = 0) {};
          should become
          ClientThread(QObject *parent = 0) :QThread(parent){};

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          M 1 Reply Last reply
          0
          • VRoninV VRonin

            from client_thread.start(); I see the thread is created on the stack, are you sure it does not go out of scope? QThread::start does not block the main thread.

            Could you show us the method where you call start() or try making client_thread a pointer to ClientThread and do

            client_thread=new ClientThread;
            connect(client_thread,&ClientThread::finished,client_thread,&ClientThread::deleteLater);
            client_thread->start();
            

            P.S.
            When reimplementing any QObject you should always call the base class constructor to avoid breaking Qt parent-child system
            ClientThread(QObject *parent = 0) {};
            should become
            ClientThread(QObject *parent = 0) :QThread(parent){};

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

            sure @VRonin

            client_thread is a member of a class deriving from QDialog.
            I call client_thread.start() start from a button slot.

            1 Reply Last reply
            0
            • M Milo

              I am trying to use a QTcpSocket from a worker thread like in this example http://doc.qt.io/qt-5/qtnetwork-blockingfortuneclient-example.html

              The socket connects properly.

              However it fails to detects when the host disconnects. So the thread remains stuck in the loop.

              If i create the socket in the main thread, it detects the disconnection properly.

              class ClientThread : public QThread
              {
              Q_OBJECT

              public:
                  ClientThread(QObject *parent = 0) {};
                  ~ClientThread() {};
              
                  void run() Q_DECL_OVERRIDE;
              

              };

              void ClientThread::run()
              {
              QTcpSocket socket;
              socket.connectToHost(SERVER, PORT);

              if (socket.waitForConnected(TIMEOUT)) 
              {
                  // sleep as long as connected
                  while(socket.state() == QAbstractSocket::SocketState::ConnectedState)
                  {
                      QThread::msleep(10);
                  }
              
                  // should exit here when host disconnects
                  QThread::msleep(10);
              }
              

              }

              // from Main thread I call this
              client_thread.start();

              Why is that?

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

              @Milo
              This code can't work simply because events are not processed for the thread. This means all QSocketNotifiers are stuck and the state can't be changed because of the endless loop. Change that or use the async API.

              @VRonin
              Additional implication of the above is that you can't have signals emitted from other threads execute slots in the current (when connected with Qt::QueuedConnection/Qt::AutoConnection/Qt::BlockingQueuedConnection).

              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