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 not emitted, but QTcpServer::waitForNewConnection works

QTcpServer: newConnection not emitted, but QTcpServer::waitForNewConnection works

Scheduled Pinned Locked Moved Solved General and Desktop
qtcpserverqtcpsocketqtnetwork
5 Posts 3 Posters 829 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.
  • M Offline
    M Offline
    Moritz Spiller
    wrote on 12 Sept 2021, 20:33 last edited by
    #1

    Hi,
    I'm using Qt 5.15 on Windows 10 to create a simple TCP-Server that will receive data from a raspberry pi acting as client (I previously used a python program to receive data from the pi, so I know that the code on the pi works).

    The code for my new qt application is based on QT's fortune server example. The problem is that neither the QTcpServer::newConnection, nor the QTcpSocket::readyRead signals are emitted. However, if I'm using the blocking versions QTcpServer::waitForNewConnection and QTcpSocket::waitForReadyRead, everything works fine and I can read data from the stream. I suspected that there is no event loop running, but an implemented QPushButton works fine.

    Can anyone help and guide me towards the problem, any hint is appreciated?

    My Code:

    wifistream.h

    #ifndef WIFISTREAM_H
    #define WIFISTREAM_H
    
    #include <QObject>
    #include <QString>
    #include <QVector>
    #include <QtNetwork>
    
    QT_BEGIN_NAMESPACE
    class QLabel;
    class QTcpServer;
    QT_END_NAMESPACE
    
    class wifiStream : public QObject
    {
        Q_OBJECT
    
    public:
        explicit wifiStream();
        bool getStatus();
    
    private slots:
        void accept_connection();
        void read();
    
    private:
        void initServer();
        void write();
        void disconnect();
    
        QTcpServer *tcpServer = nullptr;
        QTcpSocket *clientConnection = nullptr;
        QVector<QString> fortunes;
    };
    
    #endif // WIFISTREAM_H
    

    wifistream.cpp

    #include "wifistream.h"
    #include <QtWidgets>
    #include <QtCore>
    
    wifiStream::wifiStream()
    {
        initServer();
    
        qDebug() << connect(tcpServer, &QTcpServer::newConnection, this, &wifiStream::accept_connection);
    
    //    tcpServer->waitForNewConnection(10000);
    }
    
    void wifiStream::initServer()
    {
        QString ipAddress;
        QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
    
        // use the first non-localhost IPv4 address
        for (int i = 0; i < ipAddressesList.size(); ++i) {
            if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
                ipAddressesList.at(i).toIPv4Address() &&
                ipAddressesList.at(i).toString().contains("137")) {
                ipAddress = ipAddressesList.at(i).toString();
                break;
            }
        }
    
        // if we did not find one, use IPv4 localhost
        if (ipAddress.isEmpty())
            ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
    
        tcpServer = new QTcpServer(this);
        if (!tcpServer->listen(QHostAddress(ipAddress), 80)) {
            return;
        }
    
        qDebug() << ipAddress;
        qDebug() << tcpServer->serverPort();
        qDebug() << tcpServer->isListening();
        qDebug() << tcpServer->serverAddress();
    }
    
    //! [4]
    void wifiStream::accept_connection()
    {
        qDebug() << "new connection";
    
        clientConnection = tcpServer->nextPendingConnection();
    
        qDebug() << clientConnection->peerName();
        qDebug() << clientConnection->peerAddress();
    
    //    connect(clientConnection, &QAbstractSocket::connected,
    //            this, &wifiStream::read);
        connect(clientConnection, &QAbstractSocket::disconnected,
                clientConnection, &QObject::deleteLater);
        qDebug() << connect(clientConnection, &QAbstractSocket::readyRead,
                this, &wifiStream::read);
    
    //    clientConnection->waitForReadyRead(30000);
        qDebug() << "done waiting for read";
    }
    
    void wifiStream::disconnect()
    {
        clientConnection->disconnectFromHost();
    }
    
    void wifiStream::read()
    {
        for (;;) {
            //qDebug() <<"here C1 bytes = " << clientConnection->bytesAvailable();
            QDataStream in(clientConnection);
            //in.setVersion(QDataStream::Qt_5_15);
    
            if (clientConnection->bytesAvailable() != 0) {
                qDebug() << "Bytes available : " << clientConnection->bytesAvailable();
                QString nextFortune;
                in >> nextFortune;
                qDebug() << nextFortune;
                char* b = new char[clientConnection->bytesAvailable()];
                qDebug() << in.readRawData(b, clientConnection->bytesAvailable());
                qDebug() << b;
            }
        }
    }
    

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QObject>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
        void gen_data();
    
    private:
        Ui::MainWindow *ui;
    
    signals:
        void new_sample(const int &sample);
    
    private slots:
        void on_testButton_clicked();
    };
    #endif // MAINWINDOW_H
    
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <chrono>
    #include <thread>
    #include "cbuffer.h"
    #include "processing.h"
    #include "wifistream.h"
    #include <QPushButton>
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        wifiStream s;
    }
    

    The processing and cbuffer classes are not used in this version of the code.

    And to add everythng relevant, main.cpp

    #include "mainwindow.h"
    
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }
    
    
    J 1 Reply Last reply 13 Sept 2021, 06:11
    0
    • M Offline
      M Offline
      mrjj
      Lifetime Qt Champion
      wrote on 12 Sept 2021, 20:39 last edited by mrjj 9 Dec 2021, 20:40
      #2

      Hi
      You code looks good and structure so I wonder if its just a paste error.
      You show.

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

      Here "s" is a local variable that is deleted as soon as ctor ends. So using async calls would never be
      able to work as it's dead long before.

      I expect something like
      wifiStream *s = new wifiStream;

      as to have it live longer that constructor of MainWindow.

      M 1 Reply Last reply 13 Sept 2021, 14:27
      3
      • M Moritz Spiller
        12 Sept 2021, 20:33

        Hi,
        I'm using Qt 5.15 on Windows 10 to create a simple TCP-Server that will receive data from a raspberry pi acting as client (I previously used a python program to receive data from the pi, so I know that the code on the pi works).

        The code for my new qt application is based on QT's fortune server example. The problem is that neither the QTcpServer::newConnection, nor the QTcpSocket::readyRead signals are emitted. However, if I'm using the blocking versions QTcpServer::waitForNewConnection and QTcpSocket::waitForReadyRead, everything works fine and I can read data from the stream. I suspected that there is no event loop running, but an implemented QPushButton works fine.

        Can anyone help and guide me towards the problem, any hint is appreciated?

        My Code:

        wifistream.h

        #ifndef WIFISTREAM_H
        #define WIFISTREAM_H
        
        #include <QObject>
        #include <QString>
        #include <QVector>
        #include <QtNetwork>
        
        QT_BEGIN_NAMESPACE
        class QLabel;
        class QTcpServer;
        QT_END_NAMESPACE
        
        class wifiStream : public QObject
        {
            Q_OBJECT
        
        public:
            explicit wifiStream();
            bool getStatus();
        
        private slots:
            void accept_connection();
            void read();
        
        private:
            void initServer();
            void write();
            void disconnect();
        
            QTcpServer *tcpServer = nullptr;
            QTcpSocket *clientConnection = nullptr;
            QVector<QString> fortunes;
        };
        
        #endif // WIFISTREAM_H
        

        wifistream.cpp

        #include "wifistream.h"
        #include <QtWidgets>
        #include <QtCore>
        
        wifiStream::wifiStream()
        {
            initServer();
        
            qDebug() << connect(tcpServer, &QTcpServer::newConnection, this, &wifiStream::accept_connection);
        
        //    tcpServer->waitForNewConnection(10000);
        }
        
        void wifiStream::initServer()
        {
            QString ipAddress;
            QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
        
            // use the first non-localhost IPv4 address
            for (int i = 0; i < ipAddressesList.size(); ++i) {
                if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
                    ipAddressesList.at(i).toIPv4Address() &&
                    ipAddressesList.at(i).toString().contains("137")) {
                    ipAddress = ipAddressesList.at(i).toString();
                    break;
                }
            }
        
            // if we did not find one, use IPv4 localhost
            if (ipAddress.isEmpty())
                ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
        
            tcpServer = new QTcpServer(this);
            if (!tcpServer->listen(QHostAddress(ipAddress), 80)) {
                return;
            }
        
            qDebug() << ipAddress;
            qDebug() << tcpServer->serverPort();
            qDebug() << tcpServer->isListening();
            qDebug() << tcpServer->serverAddress();
        }
        
        //! [4]
        void wifiStream::accept_connection()
        {
            qDebug() << "new connection";
        
            clientConnection = tcpServer->nextPendingConnection();
        
            qDebug() << clientConnection->peerName();
            qDebug() << clientConnection->peerAddress();
        
        //    connect(clientConnection, &QAbstractSocket::connected,
        //            this, &wifiStream::read);
            connect(clientConnection, &QAbstractSocket::disconnected,
                    clientConnection, &QObject::deleteLater);
            qDebug() << connect(clientConnection, &QAbstractSocket::readyRead,
                    this, &wifiStream::read);
        
        //    clientConnection->waitForReadyRead(30000);
            qDebug() << "done waiting for read";
        }
        
        void wifiStream::disconnect()
        {
            clientConnection->disconnectFromHost();
        }
        
        void wifiStream::read()
        {
            for (;;) {
                //qDebug() <<"here C1 bytes = " << clientConnection->bytesAvailable();
                QDataStream in(clientConnection);
                //in.setVersion(QDataStream::Qt_5_15);
        
                if (clientConnection->bytesAvailable() != 0) {
                    qDebug() << "Bytes available : " << clientConnection->bytesAvailable();
                    QString nextFortune;
                    in >> nextFortune;
                    qDebug() << nextFortune;
                    char* b = new char[clientConnection->bytesAvailable()];
                    qDebug() << in.readRawData(b, clientConnection->bytesAvailable());
                    qDebug() << b;
                }
            }
        }
        

        mainwindow.h

        #ifndef MAINWINDOW_H
        #define MAINWINDOW_H
        
        #include <QMainWindow>
        #include <QObject>
        
        QT_BEGIN_NAMESPACE
        namespace Ui { class MainWindow; }
        QT_END_NAMESPACE
        
        class MainWindow : public QMainWindow
        {
            Q_OBJECT
        
        public:
            MainWindow(QWidget *parent = nullptr);
            ~MainWindow();
        
            void gen_data();
        
        private:
            Ui::MainWindow *ui;
        
        signals:
            void new_sample(const int &sample);
        
        private slots:
            void on_testButton_clicked();
        };
        #endif // MAINWINDOW_H
        
        

        mainwindow.cpp

        #include "mainwindow.h"
        #include "ui_mainwindow.h"
        #include <chrono>
        #include <thread>
        #include "cbuffer.h"
        #include "processing.h"
        #include "wifistream.h"
        #include <QPushButton>
        
        MainWindow::MainWindow(QWidget *parent)
            : QMainWindow(parent)
            , ui(new Ui::MainWindow)
        {
            ui->setupUi(this);
        
            wifiStream s;
        }
        

        The processing and cbuffer classes are not used in this version of the code.

        And to add everythng relevant, main.cpp

        #include "mainwindow.h"
        
        #include <QApplication>
        
        int main(int argc, char *argv[])
        {
            QApplication a(argc, argv);
            MainWindow w;
            w.show();
            return a.exec();
        }
        
        
        J Offline
        J Offline
        J.Hilk
        Moderators
        wrote on 13 Sept 2021, 06:11 last edited by
        #3

        @Moritz-Spiller so, why the infinite loop in read ?

        void wifiStream::read()
        {
            for (;;) {
        

        that is blocking the event loop and prevent signals from being processed. Remove it, and check if you're suddenly seeing debug prints ;)


        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        1 Reply Last reply
        5
        • M mrjj
          12 Sept 2021, 20:39

          Hi
          You code looks good and structure so I wonder if its just a paste error.
          You show.

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

          Here "s" is a local variable that is deleted as soon as ctor ends. So using async calls would never be
          able to work as it's dead long before.

          I expect something like
          wifiStream *s = new wifiStream;

          as to have it live longer that constructor of MainWindow.

          M Offline
          M Offline
          Moritz Spiller
          wrote on 13 Sept 2021, 14:27 last edited by
          #4

          @mrjj thanks a lot, this was the problem. I was not aware of that..

          1 Reply Last reply
          0
          • M Offline
            M Offline
            Moritz Spiller
            wrote on 14 Sept 2021, 13:18 last edited by
            #5

            @J-Hilk thanks for your comment. I put that to read continuously from the buffer, but of course it is not necessary as soon as the signal/slot mechansim works.

            1 Reply Last reply
            1

            2/5

            12 Sept 2021, 20:39

            • Login

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