1

谁能告诉我我这样做是否正确?

使用 Qt,我通过继承 QTcpServer 类来实现 TCP 服务器。在传入的连接上,我创建了一个新线程、一个新的 Worker 对象,并将该对象移动到新线程并启动该线程。从这里开始,服务器一直在监听新客户端,然后每个线程都在其对象 Worker 的运行方法中。

现在,我创建了一个计时器,因为我需要基于 1 秒的间隔和播放歌曲时向每个客户端发送更新。在 readyRead 插槽中,我使用 readAll 读取数据,然后执行一些工作并发送回复。

但是,当我回到我的运行方法时,我只需要继续向客户端发送歌曲数据更新(客户端没有响应)。这一切都应该进入一个while(true)循环然后我检查一些布尔值来启动和停止计时器吗?我需要发送的曲目信息是歌曲进度时间。

我想我的问题是,我应该这样做吗?这似乎有点复杂,但话又说回来,这对你来说是并发性的。基本上,当某些条件为真时,我需要 TCP 服务器反复向客户端发送数据。我觉得只是一个无休止的 while 循环来检查何时启动和停止计时器是无用的工作。

发布代码会更清楚吗?

4

1 回答 1

1

这个问题是一个非常古老的问题,但也许它仍然可以提供帮助。

关于 Qt 中的线程:
许多人认为 Qt 中的并行处理就像在 .NET 中一样,您需要为每个操作另一个线程,在 qt 中这不是必需的!
在 qt 中,如果您有阻塞代码(例如计算大事或等待同步器以获取 SQLServer 的答案),您只需要一个线程

如果我对您的理解正确,您就没有这样的阻塞操作。
所以我编写了一个非常小的 TcpServer,没有继承也没有单个线程(当然除了主 eventloop 线程),希望能解决您的问题并帮助其他人:

#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 回答