GUI of Fortune server example with multithreading in Qt 6
-
I am implementing a fortune server example with multi threading. I have used this example "https://doc.qt.io/qt-5/qtnetwork-threadedfortuneserver-example.html" and I want to make a UI for. It's working fine but the server is not sending the message to the client . I am sending the message like this in dthread.cpp file
QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_6_0); out << text; tcpSocket->write(block);
and It's not even reading the message that the client is sending. Can anyone tell me what is the issue. I have attached my whole code below.
QT += core gui QT += network widgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp \ mainwindow.cpp\ fthread.cpp \ fserver.cpp HEADERS += \ mainwindow.h\ fthread.h \ fserver.h FORMS += \ mainwindow.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target
fserver.h
#ifndef FSERVER_H #define FSERVER_H #include <QStringList> #include <QTcpServer> class fserver : public QTcpServer { Q_OBJECT public: fserver(QObject *parent = nullptr); protected: void incomingConnection(qintptr socketDescriptor) override; private: QStringList fortunes; }; //! [0] #endif // FSERVER_H
fthread.h
#ifndef FTHREAD_H #define FTHREAD_H #include <QThread> #include <QTcpSocket> #include <QTcpServer> //! [0] class fthread : public QThread { Q_OBJECT public: fthread(int socketDescriptor, const QString &fortune, QObject *parent); fthread(QObject *pwgt); QTcpServer *tcpServer; void run() override; signals: void error(QTcpSocket::SocketError socketError); void gotNewMesssage(QString msg); public slots: void readyRead(); private: int socketDescriptor; QString text="mesage from server"; QTcpSocket *tcpSocket; }; //! [0] #endif // FTHREAD_H
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "fserver.h" #include "fthread.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_connect_clicked(); void gotNewMesssage(QString msg); private: Ui::MainWindow *ui; fserver server; fthread *threadobj; }; #endif // MAINWINDOW_H
fserver.cpp
#include "fserver.h" #include "fthread.h" #include <QRandomGenerator> #include <stdlib.h> //! [0] fserver::fserver(QObject *parent) : QTcpServer(parent) { fortunes << tr("You've been leading a dog's life. Stay off the furniture.") << tr("You've got to think about tomorrow.") << tr("You will be surprised by a loud noise.") << tr("You will feel hungry again in another hour.") << tr("You might have mail.") << tr("You cannot kill time without injuring eternity.") << tr("Computers are not intelligent. They only think they are."); } //! [0] //! [1] void fserver::incomingConnection(qintptr socketDescriptor) { QString fortune = fortunes.at(QRandomGenerator::global()->bounded(fortunes.size())); fthread *thread = new fthread(socketDescriptor,fortune, this); connect(thread, &fthread::finished, thread, &fthread::deleteLater); thread->start(); }
fthread.cpp
#include "fthread.h" #include <QtNetwork> fthread::fthread(int socketDescriptor, const QString &fortune, QObject *parent) : QThread(parent), socketDescriptor(socketDescriptor), text(fortune) { } fthread::fthread(QObject *pwgt) : QThread(pwgt) { } void fthread::run() { tcpSocket = new QTcpSocket(); if (!tcpSocket->setSocketDescriptor(socketDescriptor)) { emit error(tcpSocket->error()); return; } connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection); tcpSocket->disconnectFromHost(); tcpSocket->waitForDisconnected(); } void fthread::readyRead() { // get the information QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_6_0); out << text; tcpSocket->write(block); QByteArray Data = tcpSocket->readAll(); // will write on server side window qDebug() << socketDescriptor << " Data in: " << Data; QString str; str="hello world"; emit gotNewMesssage(str); }
mainwindow.cpp
#include <stdlib.h> #include "mainwindow.h" #include "ui_mainwindow.h" #include "fserver.h" #include "fthread.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); /*threadobj= new fthread(); connect(threadobj, &fthread::gotNewMesssage, this, &MainWindow::gotNewMesssage);*/ } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_connect_clicked() { if (!server.listen(QHostAddress::Any, 54000)) { ui->textlog->append("unable to start the server"); close(); return; } ui->textlog->append("The server is listening\n"); //connect(quitButton, &QPushButton::clicked, this, &Dialog::close); }
main.cpp
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
-
First question: why on hell do you think you need threads here?
Second:
void fserver::incomingConnection(qintptr socketDescriptor)
{fthread *thread = new fthread(); connect(thread, &fthread::finished, thread, &fthread::deleteLater); thread->start();
}
Where do you initialize fthread::tcpServer (whyever this is needed) and fthread::socketDescriptor
-
@Christian-Ehrlicher It is my assignment and I need to do multi threading here. Also, I've edited my code after initializing socketdescriptor
-
@fari35 said in GUI of Fortune server example with multithreading in Qt 6:
tcpSocket->disconnectFromHost(); tcpSocket->waitForDisconnected();
You know what they're doing? How do you expect that you receive something when you immediately close the socket?
-
@Christian-Ehrlicher I've first connected it to the readyread() funtion in fthread.h class.
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead())); tcpSocket->disconnectFromHost(); tcpSocket->waitForDisconnected();
-
@fari35 said in GUI of Fortune server example with multithreading in Qt 6:
I've first connected it to the readyread() funtion in fthread.h class.
And then you directly close the socket... so again - why do you think you should receive something.
Please read the documentation when you want to use a QThread (you use the second option).
-
It is very hard for an individual (or a group) to debug your whole program (its design and its implementation) via a forum. This is not likely to succeed, in my opinion.
To have success in a Q&A forum, the problem statement needs to be minimized.
In your case, @fari35 , I would highly recommend that you start by only compiling and running the exact "untouched" sample code first:
Also compiling and run the exact unedited official client sample:
Make sure all of that works first. I was able to compile and launch both of those with no issue, and this is what I see:
Once you do that, then start tracking your changes using
git
, and make one tiny change a time (in order to work slowly towards whatever your goal or assignment is).When you make one tiny change (as small as editing or adding just one line of code) and the change fails to do what you expect, then you can use the time-tested bug-reporting technique of:
- State what you did (the single tiny change).
- State what you expected.
- State what actually happened.