Extending FortuneServer to 4 client



  • Hello,

    I'm trying to extend the fortune server to periodically send the data on the same socket and not on the Get Fortune button press. But the program crashes after only one sendFortune. running the gdb the program crashes over clientConnection->write(block); as the clientConnection is 0x00 . The following are the changes made to the code. If any one can please point me the error, or point to the example where a single QTcpServer handling 4 clients by sending unique data I'll be greateful.

    //your code here
    
    #include <QtWidgets>
    #include <QtNetwork>
    
    #include <stdlib.h>
    
    #include "server.h"
    
    Server::Server(QWidget *parent)
        : QDialog(parent)
        , statusLabel(new QLabel)
        , tcpServer(Q_NULLPTR)
        , networkSession(0)
    {
        setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
        statusLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
        ConnectiontToClient = false;
        QNetworkConfigurationManager manager;
        if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
            // Get saved network configuration
            QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
            settings.beginGroup(QLatin1String("QtNetwork"));
            const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
            settings.endGroup();
    
            // If the saved network configuration is not currently discovered use the system default
            QNetworkConfiguration config = manager.configurationFromIdentifier(id);
            if ((config.state() & QNetworkConfiguration::Discovered) !=
                    QNetworkConfiguration::Discovered) {
                config = manager.defaultConfiguration();
            }
    
            networkSession = new QNetworkSession(config, this);
            connect(networkSession, &QNetworkSession::opened, this, &Server::sessionOpened);
    
            statusLabel->setText(tr("Opening network session."));
            networkSession->open();
        } else {
            sessionOpened();
        }
    
        //! [2]
        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.");
        //! [2]
        QPushButton *quitButton = new QPushButton(tr("Quit"));
        quitButton->setAutoDefault(false);
        connect(quitButton, &QAbstractButton::clicked, this, &QWidget::close);
        //! [3]
        connect(tcpServer, &QTcpServer::newConnection, this, &Server::setAFlag);
        //! [3]
    
        QHBoxLayout *buttonLayout = new QHBoxLayout;
        buttonLayout->addStretch(1);
        buttonLayout->addWidget(quitButton);
        buttonLayout->addStretch(1);
    
        QVBoxLayout *mainLayout = Q_NULLPTR;
        if (QGuiApplication::styleHints()->showIsFullScreen() || QGuiApplication::styleHints()->showIsMaximized()) {
            QVBoxLayout *outerVerticalLayout = new QVBoxLayout(this);
            outerVerticalLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
            QHBoxLayout *outerHorizontalLayout = new QHBoxLayout;
            outerHorizontalLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Ignored));
            QGroupBox *groupBox = new QGroupBox(QGuiApplication::applicationDisplayName());
            mainLayout = new QVBoxLayout(groupBox);
            outerHorizontalLayout->addWidget(groupBox);
            outerHorizontalLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Ignored));
            outerVerticalLayout->addLayout(outerHorizontalLayout);
            outerVerticalLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
        } else {
            mainLayout = new QVBoxLayout(this);
        }
    
        mainLayout->addWidget(statusLabel);
        mainLayout->addLayout(buttonLayout);
    
        setWindowTitle(QGuiApplication::applicationDisplayName());
    
        timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(sendFortune()));
        timer->start(1000);
    
    }
    
    void Server::sessionOpened()
    {
        // Save the used configuration
        qDebug() << "sessionopened";
        if (networkSession) {
            QNetworkConfiguration config = networkSession->configuration();
            QString id;
            if (config.type() == QNetworkConfiguration::UserChoice)
                id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString();
            else
                id = config.identifier();
    
            QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
            settings.beginGroup(QLatin1String("QtNetwork"));
            settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
            settings.endGroup();
        }
    
        //! [0] //! [1]
        tcpServer = new QTcpServer(this);
        if (!tcpServer->listen()) {
            QMessageBox::critical(this, tr("Fortune Server"),
                                  tr("Unable to start the server: %1.")
                                  .arg(tcpServer->errorString()));
            close();
            return;
        }
        //! [0]
        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()) {
                ipAddress = ipAddressesList.at(i).toString();
                break;
            }
        }
        // if we did not find one, use IPv4 localhost
        if (ipAddress.isEmpty())
            ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
        statusLabel->setText(tr("The server is running on\n\nIP: %1\nport: %2\n\n"
                                "Run the Fortune Client example now.")
                             .arg(ipAddress).arg(tcpServer->serverPort()));
    
    
    
        //! [1]
    }
    
    //! [4]
    void Server::sendFortune()
    {
        //! [5]
        //!
        if(ConnectiontToClient == true)
        {
            qDebug() << "sendFortune";
            QByteArray block;
            QDataStream out(&block, QIODevice::WriteOnly);
            out.setVersion(QDataStream::Qt_4_0);
    
            out << fortunes.at(qrand() % fortunes.size());
            //! [4] //! [7]
    
            clientConnection = tcpServer->nextPendingConnection();
            connect(clientConnection, &QAbstractSocket::disconnected,
                    clientConnection, &QObject::deleteLater);
            //! [7] //! [8]
    
            clientConnection->write(block);
            //   clientConnection->disconnectFromHost();
    
        }
        //! [5]
    }
    
    void Server::setAFlag()
    {
        ConnectiontToClient = true;
    }
    

  • Qt Champions 2016

    Take a look at this. It's threaded and it's an example for my daemon module, but it's practically compatible with a console application.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.