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::newConnection() does not work when realized in another class
Forum Updated to NodeBB v4.3 + New Features

QTcpServer::newConnection() does not work when realized in another class

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 3 Posters 900 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.
  • gaosiyG gaosiy

    As title, my purpose is open the listen and when a new connection is coming, do something.
    I don't want to write all my functions in the mainwindow, so I create another class to realize this function.
    as my coding follow, I used the first kind of init(), but it does not work, I try in the second init(), it works.

    I want to know why can you tell me? this is part codes in my 2 files.

    mainwindow.cpp

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        ui->label->setText("Disconnected!");
    
        ui->pushButton_send->setEnabled(false);
    
        bool isInitialized;
    
        // the first kind of init to open listen and get connection, init() is in another class called Server
        Server server;
        isInitialized = server.init();
    
        // the second method to open listen and get connection, init() is in the same class
        isInitialized = init();
    
        qDebug()<<isInitialized;
    }
    
    int MainWindow::init()
    {
        server = new QTcpServer();
        connect(server, SIGNAL(newConnection()), this, SLOT(server_New_Connect()));
        int port = 5007;
        if(!server->listen(QHostAddress::Any,port))
        {
            ui->label_listen->setText("fail to listen");
            qDebug()<<server->errorString();
            return 0;
        }
    
        ui->label_listen->setText("listen succeed");
        return 1;
    }
    

    Server.cpp

    bool Server::init()
    {
        bool isInitialized = listen(QHostAddress(SERVER_IP), SERVER_PORT);
        if (isInitialized)
        {
            m_serverStatus = SERVER_STATUS_OK;
            QThreadPool::globalInstance()->setMaxThreadCount(QTNConst::NUM_MAX_CLIENTS);
            connect(this, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
        }
        return isInitialized;
    }
    
    KillerSmathK Offline
    KillerSmathK Offline
    KillerSmath
    wrote on last edited by
    #2

    @gaosiy
    it's very confused...
    Why are you trying to create 2 QTcpServer (maybe in same port) ? i suppose that Server Class is a derived from QTcpServer

    @Computer Science Student - Brazil
    Web Developer and Researcher
    “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

    1 Reply Last reply
    0
    • gaosiyG Offline
      gaosiyG Offline
      gaosiy
      wrote on last edited by
      #3

      thanks for replay
      when I use this code, I will use just one of these.
      I show all of them cause it will be clear.

      Biomedical Engineering Ph.D. student, China

      KillerSmathK 1 Reply Last reply
      0
      • gaosiyG gaosiy

        thanks for replay
        when I use this code, I will use just one of these.
        I show all of them cause it will be clear.

        KillerSmathK Offline
        KillerSmathK Offline
        KillerSmath
        wrote on last edited by KillerSmath
        #4

        @gaosiy
        I tested an similiar example:

        void Server::init()
        {
            bool isListening = listen(QHostAddress("127.0.0.1"), 5007);
        
            if(isListening){
                qDebug() << "IS LISTENING";
                connect(this, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
            }
        }
        
        void Server::onNewConnection()
        {
            qDebug() << "Incoming Connection";
        }
        

        The newConnection signal is invoking onNewConnection normaly.

        Note: If your class should use signal and slot feature, you need to define Q_OBJECT macro.

        class Server : public QTcpServer{
           Q_OBJECT
           // your derivered class implementation
        public:
           Server();
        };
        

        @Computer Science Student - Brazil
        Web Developer and Researcher
        “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

        gaosiyG 1 Reply Last reply
        2
        • KillerSmathK KillerSmath

          @gaosiy
          I tested an similiar example:

          void Server::init()
          {
              bool isListening = listen(QHostAddress("127.0.0.1"), 5007);
          
              if(isListening){
                  qDebug() << "IS LISTENING";
                  connect(this, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
              }
          }
          
          void Server::onNewConnection()
          {
              qDebug() << "Incoming Connection";
          }
          

          The newConnection signal is invoking onNewConnection normaly.

          Note: If your class should use signal and slot feature, you need to define Q_OBJECT macro.

          class Server : public QTcpServer{
             Q_OBJECT
             // your derivered class implementation
          public:
             Server();
          };
          
          gaosiyG Offline
          gaosiyG Offline
          gaosiy
          wrote on last edited by
          #5

          @KillerSmath said in QTcpServer::newConnection() does not work when realized in another class:

          Q_OBJECT

          thanks again!
          I can also work it when test in a console application.
          but in mainwindow (with ui), it does not work.

          Biomedical Engineering Ph.D. student, China

          KillerSmathK 1 Reply Last reply
          0
          • gaosiyG gaosiy

            @KillerSmath said in QTcpServer::newConnection() does not work when realized in another class:

            Q_OBJECT

            thanks again!
            I can also work it when test in a console application.
            but in mainwindow (with ui), it does not work.

            KillerSmathK Offline
            KillerSmathK Offline
            KillerSmath
            wrote on last edited by KillerSmath
            #6

            @gaosiy
            What exactly do you pretent to change or access on mainwindow ?

            You can capture the Server newConnection Signal and invoke a MainWindow slots as onNewConnectionServer()

            /////
            //h file
            /////
            class MainWindow : public QMainWindow
            {
                Q_OBJECT
            
            public:
                explicit MainWindow(QWidget *parent = 0);
                ~MainWindow();
            private slots:
                void onNewConnectionServer();
            private:
                Ui::MainWindow *ui;
                Server server;
            };
            ////
            // cpp file
            //////
            MainWindow::MainWindow(QWidget *parent) :
                QMainWindow(parent),
                ui(new Ui::MainWindow)
            {
                ui->setupUi(this);
            
                connect(&server, SIGNAL(newConnection()), this, SLOT(onNewConnectionServer()));
                server.init();
            }
            
            MainWindow::~MainWindow()
            {
                delete ui;
            }
            
            void MainWindow::onNewConnectionServer()
            {
                // acess ui
            }
            

            @Computer Science Student - Brazil
            Web Developer and Researcher
            “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

            1 Reply Last reply
            0
            • gaosiyG Offline
              gaosiyG Offline
              gaosiy
              wrote on last edited by
              #7

              @KillerSmath said in QTcpServer::newConnection() does not work when realized in another class:

              MainWindow::MainWindow(QWidget *parent) :
              QMainWindow(parent),
              ui(new Ui::MainWindow)
              {
              ui->setupUi(this);

              connect(&server, SIGNAL(newConnection()), this, SLOT(onNewConnectionServer()));
              server.init();
              

              }

              thanks!
              in this code, can the nowconnection in the connect work if you put it in init() in another class?
              I know it can work if I put it in the constructor directly

              Biomedical Engineering Ph.D. student, China

              KillerSmathK 1 Reply Last reply
              0
              • gaosiyG gaosiy

                @KillerSmath said in QTcpServer::newConnection() does not work when realized in another class:

                MainWindow::MainWindow(QWidget *parent) :
                QMainWindow(parent),
                ui(new Ui::MainWindow)
                {
                ui->setupUi(this);

                connect(&server, SIGNAL(newConnection()), this, SLOT(onNewConnectionServer()));
                server.init();
                

                }

                thanks!
                in this code, can the nowconnection in the connect work if you put it in init() in another class?
                I know it can work if I put it in the constructor directly

                KillerSmathK Offline
                KillerSmathK Offline
                KillerSmath
                wrote on last edited by
                #8

                @gaosiy
                You can... but it is strange idea...

                2 Ways to achieve it:

                1. Storage a pointer to MainWindow object
                2. Pass MainWindow as Parent of Server Object

                Example of how you could implement it by Parent Method:

                MainWindow::MainWindow()
                {
                ...
                Server *server = new Server(this);
                server->init();
                ...
                }
                

                Change Server construtor to receive QObject pointer

                class Server : public QTcpServer
                {
                    Q_OBJECT
                public:
                    Server(QObject *parent);
                    ~Server();
                
                    void init();
                };
                

                Call QTcpServer Construtor (Base Class) passing parent

                Server::Server(QObject *parent) : QTcpServer(parent) // call QTcpServer construtor
                {
                
                }
                

                Cast the parent to MainWindow (parent) and create the connection

                void Server::init()
                {
                    bool isListening = listen(QHostAddress("127.0.0.1"), 5007);
                
                    if(isListening){
                        MainWindow *window = qobject_cast<MainWindow*>(parent());
                        connect(this, SIGNAL(newConnection()), window, SLOT(onNewConnectionServer()));
                    }
                }
                

                But why necessarily do you need to create the connection inside of Init function ?

                @Computer Science Student - Brazil
                Web Developer and Researcher
                “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

                gaosiyG 2 Replies Last reply
                0
                • KillerSmathK KillerSmath

                  @gaosiy
                  You can... but it is strange idea...

                  2 Ways to achieve it:

                  1. Storage a pointer to MainWindow object
                  2. Pass MainWindow as Parent of Server Object

                  Example of how you could implement it by Parent Method:

                  MainWindow::MainWindow()
                  {
                  ...
                  Server *server = new Server(this);
                  server->init();
                  ...
                  }
                  

                  Change Server construtor to receive QObject pointer

                  class Server : public QTcpServer
                  {
                      Q_OBJECT
                  public:
                      Server(QObject *parent);
                      ~Server();
                  
                      void init();
                  };
                  

                  Call QTcpServer Construtor (Base Class) passing parent

                  Server::Server(QObject *parent) : QTcpServer(parent) // call QTcpServer construtor
                  {
                  
                  }
                  

                  Cast the parent to MainWindow (parent) and create the connection

                  void Server::init()
                  {
                      bool isListening = listen(QHostAddress("127.0.0.1"), 5007);
                  
                      if(isListening){
                          MainWindow *window = qobject_cast<MainWindow*>(parent());
                          connect(this, SIGNAL(newConnection()), window, SLOT(onNewConnectionServer()));
                      }
                  }
                  

                  But why necessarily do you need to create the connection inside of Init function ?

                  gaosiyG Offline
                  gaosiyG Offline
                  gaosiy
                  wrote on last edited by
                  #9

                  @KillerSmath

                  thanks.
                  I can show you why i want to achieve it at the other class.
                  this file is my first version of tcp communication without any UI

                  //QTNetworkDemo.cpp
                  #include "QTNetworkDemo.h"
                  #include "client/QTNClient.h"
                  #include "server/QTNServer.h"
                  #include <QTNConst.h>
                  
                  QTNetworkDemo::QTNetworkDemo(int argc, char *argv[])
                  : QCoreApplication(argc, argv),
                  CLIENT_CHOICE_STR(QTNConst::CLIENT_CHOICE_STR),
                  SERVER_CHOICE_STR(QTNConst::SERVER_CHOICE_STR),
                  EXIT_CHOICE_STR(QTNConst::EXIT_CHOICE_STR),
                  m_opCode(OP_CODE_ERROR)
                  {
                  
                  }
                  
                  int QTNetworkDemo::exec()
                  {
                      bool isInitialized;
                  
                      QTNServer server;
                  
                      qDebug()<<"1"<<endl;
                  
                      isInitialized = server.init();
                  
                      return QCoreApplication::exec();
                  }
                  
                  int main(int argc, char *argv[])
                  {
                      QTNetworkDemo demo(argc, argv);
                  
                      return demo.exec();
                  }
                  
                  

                  and this is server.cpp

                  //  QTNServer.cpp
                  
                  #include "QTNServer.h"
                  #include "QTNServerThread.h"
                  #include <QTNConst.h>
                  #include <QTcpSocket>
                  #include <QStringList>
                  #include <QTimer>
                  #include <QThreadPool>
                  
                  QTNServer::QTNServer()
                  : SERVER_IP(QTNConst::SERVER_IP),
                  SERVER_PORT(QTNConst::SERVER_PORT),
                  m_serverStatus(SERVER_STATUS_IDLE),
                  m_numMaxClients(QTNConst::NUM_MAX_CLIENTS)
                  {
                  
                  }
                  
                  bool QTNServer::init()
                  {
                      std::cout << getStatusDescription().c_str() << "is initializing " << "ip: " << SERVER_IP << ", port: " << SERVER_PORT << "\n";
                  
                      bool isInitialized = listen(QHostAddress(SERVER_IP), SERVER_PORT);
                      if (isInitialized)
                      {
                          m_serverStatus = SERVER_STATUS_OK;
                          std::cout << getStatusDescription().c_str() << "is listening\n";
                          QThreadPool::globalInstance()->setMaxThreadCount(QTNConst::NUM_MAX_CLIENTS);
                          connect(this, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
                          QTimer::singleShot(1000, this, SLOT(printClients()));
                      }
                      else
                      {
                          m_serverStatus = SERVER_STATUS_NOK;
                          std::cout << getStatusDescription().c_str() << "is NOT listening\n";
                      }
                  
                      return isInitialized;
                  }
                  

                  when I use the first version, it works well.
                  but when I want to use TCP communication with UI, the same way of my method does not work
                  so I fell very strange and I can't understand why...

                  Biomedical Engineering Ph.D. student, China

                  jsulmJ 1 Reply Last reply
                  0
                  • KillerSmathK KillerSmath

                    @gaosiy
                    You can... but it is strange idea...

                    2 Ways to achieve it:

                    1. Storage a pointer to MainWindow object
                    2. Pass MainWindow as Parent of Server Object

                    Example of how you could implement it by Parent Method:

                    MainWindow::MainWindow()
                    {
                    ...
                    Server *server = new Server(this);
                    server->init();
                    ...
                    }
                    

                    Change Server construtor to receive QObject pointer

                    class Server : public QTcpServer
                    {
                        Q_OBJECT
                    public:
                        Server(QObject *parent);
                        ~Server();
                    
                        void init();
                    };
                    

                    Call QTcpServer Construtor (Base Class) passing parent

                    Server::Server(QObject *parent) : QTcpServer(parent) // call QTcpServer construtor
                    {
                    
                    }
                    

                    Cast the parent to MainWindow (parent) and create the connection

                    void Server::init()
                    {
                        bool isListening = listen(QHostAddress("127.0.0.1"), 5007);
                    
                        if(isListening){
                            MainWindow *window = qobject_cast<MainWindow*>(parent());
                            connect(this, SIGNAL(newConnection()), window, SLOT(onNewConnectionServer()));
                        }
                    }
                    

                    But why necessarily do you need to create the connection inside of Init function ?

                    gaosiyG Offline
                    gaosiyG Offline
                    gaosiy
                    wrote on last edited by
                    #10

                    @KillerSmath

                    And I find when I do like this in exec()

                    //return QCoreApplication::exec();
                    

                    it does not work as the UI version.
                    I dont know why.

                    Biomedical Engineering Ph.D. student, China

                    1 Reply Last reply
                    0
                    • gaosiyG gaosiy

                      @KillerSmath

                      thanks.
                      I can show you why i want to achieve it at the other class.
                      this file is my first version of tcp communication without any UI

                      //QTNetworkDemo.cpp
                      #include "QTNetworkDemo.h"
                      #include "client/QTNClient.h"
                      #include "server/QTNServer.h"
                      #include <QTNConst.h>
                      
                      QTNetworkDemo::QTNetworkDemo(int argc, char *argv[])
                      : QCoreApplication(argc, argv),
                      CLIENT_CHOICE_STR(QTNConst::CLIENT_CHOICE_STR),
                      SERVER_CHOICE_STR(QTNConst::SERVER_CHOICE_STR),
                      EXIT_CHOICE_STR(QTNConst::EXIT_CHOICE_STR),
                      m_opCode(OP_CODE_ERROR)
                      {
                      
                      }
                      
                      int QTNetworkDemo::exec()
                      {
                          bool isInitialized;
                      
                          QTNServer server;
                      
                          qDebug()<<"1"<<endl;
                      
                          isInitialized = server.init();
                      
                          return QCoreApplication::exec();
                      }
                      
                      int main(int argc, char *argv[])
                      {
                          QTNetworkDemo demo(argc, argv);
                      
                          return demo.exec();
                      }
                      
                      

                      and this is server.cpp

                      //  QTNServer.cpp
                      
                      #include "QTNServer.h"
                      #include "QTNServerThread.h"
                      #include <QTNConst.h>
                      #include <QTcpSocket>
                      #include <QStringList>
                      #include <QTimer>
                      #include <QThreadPool>
                      
                      QTNServer::QTNServer()
                      : SERVER_IP(QTNConst::SERVER_IP),
                      SERVER_PORT(QTNConst::SERVER_PORT),
                      m_serverStatus(SERVER_STATUS_IDLE),
                      m_numMaxClients(QTNConst::NUM_MAX_CLIENTS)
                      {
                      
                      }
                      
                      bool QTNServer::init()
                      {
                          std::cout << getStatusDescription().c_str() << "is initializing " << "ip: " << SERVER_IP << ", port: " << SERVER_PORT << "\n";
                      
                          bool isInitialized = listen(QHostAddress(SERVER_IP), SERVER_PORT);
                          if (isInitialized)
                          {
                              m_serverStatus = SERVER_STATUS_OK;
                              std::cout << getStatusDescription().c_str() << "is listening\n";
                              QThreadPool::globalInstance()->setMaxThreadCount(QTNConst::NUM_MAX_CLIENTS);
                              connect(this, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
                              QTimer::singleShot(1000, this, SLOT(printClients()));
                          }
                          else
                          {
                              m_serverStatus = SERVER_STATUS_NOK;
                              std::cout << getStatusDescription().c_str() << "is NOT listening\n";
                          }
                      
                          return isInitialized;
                      }
                      

                      when I use the first version, it works well.
                      but when I want to use TCP communication with UI, the same way of my method does not work
                      so I fell very strange and I can't understand why...

                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #11

                      @gaosiy said in QTcpServer::newConnection() does not work when realized in another class:

                      but when I want to use TCP communication with UI, the same way of my method does not work

                      You should not do it same way in a UI application: your UI application will already have an event loop.
                      Doing the connect in MainWindow constructor (or its init() method) is perfectly valid and the right thing to do. Your server should not know anything about your UI, so it can't do the connect to UI as it does not know anything about it :-)

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      1

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved