1

私がこれを正しく行っているかどうか、誰か教えてもらえますか?

Qt の使用 QTcpServer クラスから継承して TCP サーバーを実装しています。着信接続で、新しいスレッド、新しい Worker オブジェクトを作成し、オブジェクトを新しいスレッドに移動してスレッドを開始します。ここから、サーバーは新しいクライアントをリッスンし続け、各スレッドは Worker オブジェクトの run メソッドに入ります。

ここで、タイマーを作成します。これは、1 秒間隔に基づいて各クライアントに更新を送信する必要があり、曲の再生中にも行う必要があるためです。readyRead スロットでは、readAll を使用してデータを読み取り、いくつかの作業を実行して応答を送信します。

ただし、実行メソッドに戻ると、曲データの更新をクライアントに送信し続ける必要があります (クライアントからの応答はありません)。これはすべて while(true) ループに入ってから、ブール値をチェックしてタイマーを開始および停止する必要がありますか? 私が送信する必要があるトラック情報は、曲の進行時間です。

私の質問は、このようにすべきですか?少し複雑に思えますが、これも並行性です。基本的に、ある条件が真のときにクライアントにデータを繰り返し送信するには、TCP サーバーが必要です。タイマーをいつ開始していつ停止するかをチェックする無限ループだけが無駄な作業のように感じます。

コードを投稿すると、これがより明確になりますか?

4

1 に答える 1

1

この質問は非常に古いものですが、おそらくまだ役立つ可能性があります。

Qt のスレッドについて:
多くの人が Qt での並列処理について考えています。.NET では、操作ごとに別のスレッドが必要になりますが、qt ではこれは必要ありません!
qt では、大きなことを計算したり、syncron が SQLServer からの応答を待機するなどのブロック コードがある場合にのみ、スレッドが必要です。

私があなたを正しく理解していれば、そのようなブロッキング操作はありません。
したがって、継承せず、単一のスレッド(もちろんメインのイベントループスレッドを除く)なしで非常に小さなTcpServerをプログラムしました。これにより、問題が解決し、他の人を助けることができます:

#include <QObject>
#include <QSet>
#include <QTcpServer>
#include <QTcpSocket>
#include <QTimer>

class TcpServer : public QObject
{
    Q_OBJECT
    public:
        TcpServer()
        {
            // handle new connections
            this->connect(&this->serverTcp, &QTcpServer::newConnection, this, &TcpServer::handleClientConnect);

            // init client refresh timer
            this->timer.setInterval(1000);
            this->connect(&this->timer, &QTimer::timeout, this, &TcpServer::handleClientUpdates);
            this->timer.start();
        }

        bool startListen(qint16 port)
        {
            return this->serverTcp.listen(QHostAddress::Any, port);
        }

    private slots:
        void handleClientConnect()
        {
            QTcpSocket* socketClient = *this->setConnectedClients.insert(this->serverTcp.nextPendingConnection());
            this->connect(socketClient, &QTcpSocket::disconnected, this, &TcpServer::handleClientDisconnect);
            this->connect(socketClient, &QTcpSocket::readyRead, this, &TcpServer::handleClientData);
        }

        void handleClientDisconnect()
        {
            this->setConnectedClients.remove((QTcpSocket*)this->sender());
        }

        void handleClientData()
        {
            QTcpSocket* socketSender = (QTcpSocket*)this->sender();
            // handle here the data sent by the client
        }

        void handleClientUpdates()
        {
            // construct here your update data
            QByteArray baUpdateResponse = "test";

            // send update data to all connected clients
            foreach(QTcpSocket* socketClient, this->setConnectedClients) {
                socketClient->write(baUpdateResponse);
            }
        }

    private:
        QTcpServer serverTcp;
        QTimer timer;
        QSet<QTcpSocket*> setConnectedClients;
};
于 2015-05-31T12:57:38.513 に答える