Fortune Server

ネットワークサービス用のサーバーを作成する方法を示します。

このサンプルは、「Fortuneクライアント」サンプルまたは「ブロッキングFortuneクライアント」サンプルと併せて実行することを想定しています。

Fortune Serverの例のスクリーンショット

QTcpServer を使用して着信TCP接続を受け付け、接続を閉じる前に、接続してきたクライアント(「Fortune Client」サンプル)に対して、QDataStream に基づくシンプルなデータ転送プロトコルを用いてフォーチュンを書き込みます。

class Server : public QDialog
{
    Q_OBJECT

public:
    explicit Server(QWidget *parent = nullptr);

private slots:
    void sendFortune();

private:
    void initServer();

    QLabel *statusLabel = nullptr;
    QTcpServer *tcpServer = nullptr;
    QList<QString> fortunes;
};

サーバーは、着信接続を処理するためのスロットが 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;
    }
    QString ipAddress;
    const QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
    // use the first non-localhost IPv4 address
    for (const QHostAddress &entry : ipAddressesList) {
        if (entry != QHostAddress::LocalHost && entry.toIPv4Address()) {
            ipAddress = entry.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()));

コンストラクタ内で、Server オブジェクトはQTcpServer::listen() を呼び出し、任意のポートで全アドレスをリッスンするQTcpServer を設定します。その後、ラベルに選択されたポートQTcpServer を表示し、ユーザーがフォーチュンクライアントが接続すべきポートを把握できるようにします。

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.");

当サーバーは、接続してきたクライアントに送信できるランダムなフォーチュンのリストを生成します。

connect(tcpServer, &QTcpServer::newConnection, this, &Server::sendFortune);

クライアントが当サーバーに接続すると、QTcpServer がQTcpServer::newConnection()を発行します。これにより、sendFortune()スロットが呼び出されます:

void Server::sendFortune()
{
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_6_5);

    out << fortunes[QRandomGenerator::global()->bounded(fortunes.size())];

このスロットの目的は、フォーチュンのリストからランダムな一行を選択し、QDataStream を使用してQByteArray にエンコードし、接続中のソケットに書き込むことです。これは、QTcpSocket を使用してバイナリデータを転送する一般的な方法です。まず、QByteArray とQDataStream オブジェクトを作成し、bytearray をQDataStream のコンストラクタに渡します。 次に、将来のバージョンの Qt からのクライアントと確実に通信できるように、QDataStream のプロトコルバージョンを明示的にQDataStream::Qt_5_10 に設定します(QDataStream::setVersion() を参照)。続いて、ランダムなフォーチュンをストリーミングします。

    QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
    connect(clientConnection, &QAbstractSocket::disconnected,
            clientConnection, &QObject::deleteLater);

次に、QTcpServer::nextPendingConnection() を呼び出します。これにより、接続のサーバー側を表す `QTcpSocket ` が返されます。QTcpSocket::disconnected() をQObject::deleteLater() に接続することで、切断後にソケットが確実に削除されるようにします。

    clientConnection->write(block);
    clientConnection->disconnectFromHost();
}

エンコードされたフォーチュンはQTcpSocket::write() を使用して書き込まれ、最後にQTcpSocket::disconnectFromHost() を呼び出します。これにより、QTcpSocket がネットワークへのフォーチュンの書き込みを完了した後、接続が閉じられます。QTcpSocket は非同期で動作するため、データはこの関数が戻った後に書き込まれ、制御は Qt のイベントループに戻ります。 その後、ソケットが閉じられ、それに伴ってQObject::deleteLater()によってソケットが削除されます。

サンプルプロジェクト @ code.qt.io

「Fortune クライアント」および「スレッド化された Fortune サーバー」も参照してください 。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.