Fortune Server Example▲
Sélectionnez
/**
**************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
***************************************************************************
*/
#include <QtWidgets>
#include <QtNetwork>
#include <QtCore>
#include
"server.h"
Server::
Server(QWidget *
parent)
:
QDialog(parent)
, statusLabel(new
QLabel)
{
setWindowFlags(windowFlags() &
amp; ~
Qt::
WindowContextHelpButtonHint);
statusLabel-&
gt;setTextInteractionFlags(Qt::
TextBrowserInteraction);
QNetworkConfigurationManager manager;
if
(manager.capabilities() &
amp; 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() &
amp; QNetworkConfiguration::
Discovered) !=
QNetworkConfiguration::
Discovered) {
config =
manager.defaultConfiguration();
}
networkSession =
new
QNetworkSession(config, this
);
connect(networkSession, &
amp;QNetworkSession::
opened, this
, &
amp;Server::
sessionOpened);
statusLabel-&
gt;setText(tr("Opening network session."
));
networkSession-&
gt;open();
}
else
{
sessionOpened();
}
fortunes &
lt;&
lt; tr("You've been leading a dog's life. Stay off the furniture."
)
&
lt;&
lt; tr("You've got to think about tomorrow."
)
&
lt;&
lt; tr("You will be surprised by a loud noise."
)
&
lt;&
lt; tr("You will feel hungry again in another hour."
)
&
lt;&
lt; tr("You might have mail."
)
&
lt;&
lt; tr("You cannot kill time without injuring eternity."
)
&
lt;&
lt; tr("Computers are not intelligent. They only think they are."
);
auto
quitButton =
new
QPushButton(tr("Quit"
));
quitButton-&
gt;setAutoDefault(false
);
connect(quitButton, &
amp;QAbstractButton::
clicked, this
, &
amp;QWidget::
close);
connect(tcpServer, &
amp;QTcpServer::
newConnection, this
, &
amp;Server::
sendFortune);
auto
buttonLayout =
new
QHBoxLayout;
buttonLayout-&
gt;addStretch(1
);
buttonLayout-&
gt;addWidget(quitButton);
buttonLayout-&
gt;addStretch(1
);
QVBoxLayout *
mainLayout =
nullptr
;
if
(QGuiApplication::
styleHints()-&
gt;showIsFullScreen() ||
QGuiApplication::
styleHints()-&
gt;showIsMaximized()) {
auto
outerVerticalLayout =
new
QVBoxLayout(this
);
outerVerticalLayout-&
gt;addItem(new
QSpacerItem(0
, 0
, QSizePolicy::
Ignored, QSizePolicy::
MinimumExpanding));
auto
outerHorizontalLayout =
new
QHBoxLayout;
outerHorizontalLayout-&
gt;addItem(new
QSpacerItem(0
, 0
, QSizePolicy::
MinimumExpanding, QSizePolicy::
Ignored));
auto
groupBox =
new
QGroupBox(QGuiApplication::
applicationDisplayName());
mainLayout =
new
QVBoxLayout(groupBox);
outerHorizontalLayout-&
gt;addWidget(groupBox);
outerHorizontalLayout-&
gt;addItem(new
QSpacerItem(0
, 0
, QSizePolicy::
MinimumExpanding, QSizePolicy::
Ignored));
outerVerticalLayout-&
gt;addLayout(outerHorizontalLayout);
outerVerticalLayout-&
gt;addItem(new
QSpacerItem(0
, 0
, QSizePolicy::
Ignored, QSizePolicy::
MinimumExpanding));
}
else
{
mainLayout =
new
QVBoxLayout(this
);
}
mainLayout-&
gt;addWidget(statusLabel);
mainLayout-&
gt;addLayout(buttonLayout);
setWindowTitle(QGuiApplication::
applicationDisplayName());
}
void
Server::
sessionOpened()
{
// Save the used configuration
if
(networkSession) {
QNetworkConfiguration config =
networkSession-&
gt;configuration();
QString id;
if
(config.type() ==
QNetworkConfiguration::
UserChoice)
id =
networkSession-&
gt;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();
}
tcpServer =
new
QTcpServer(this
);
if
(!
tcpServer-&
gt;listen()) {
QMessageBox::
critical(this
, tr("Fortune Server"
),
tr("Unable to start the server: %1."
)
.arg(tcpServer-&
gt;errorString()));
close();
return
;
}
QString ipAddress;
QList&
lt;QHostAddress&
gt; ipAddressesList =
QNetworkInterface::
allAddresses();
// use the first non-localhost IPv4 address
for
(int
i =
0
; i &
lt; ipAddressesList.size(); ++
i) {
if
(ipAddressesList.at(i) !=
QHostAddress::
LocalHost &
amp;&
amp;
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-&
gt;setText(tr("The server is running on
\n\n
IP: %1
\n
port: %2
\n\n
"
"Run the Fortune Client example now."
)
.arg(ipAddress).arg(tcpServer-&
gt;serverPort()));
}
void
Server::
sendFortune()
{
QByteArray block;
QDataStream out(&
amp;block, QIODevice::
WriteOnly);
out.setVersion(QDataStream::
Qt_5_10);
out &
lt;&
lt; fortunes[QRandomGenerator::
global()-&
gt;bounded(fortunes.size())];
QTcpSocket *
clientConnection =
tcpServer-&
gt;nextPendingConnection();
connect(clientConnection, &
amp;QAbstractSocket::
disconnected,
clientConnection, &
amp;QObject::
deleteLater);
clientConnection-&
gt;write(block);
clientConnection-&
gt;disconnectFromHost();
}