Unsolved 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; }
-
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.