QTcpServer: newConnection not emitted, but QTcpServer::waitForNewConnection works
-
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(); }
-
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.
-
@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 ;)
-
@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.