Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 实现TCP服务器_Qt - Fatal编程技术网

Qt 实现TCP服务器

Qt 实现TCP服务器,qt,Qt,谁能告诉我我做得对吗 使用Qt,我通过继承qtcserver类来实现TCP服务器。在传入连接上,我创建一个新线程,一个新的Worker对象,然后将该对象移动到新线程并启动该线程。从这里开始,服务器不断侦听新的客户机,然后每个线程都处于对象工作线程的run方法中 现在,我创建了一个计时器,因为我需要根据1秒的间隔和播放歌曲的时间向每个客户端发送更新。在readyRead插槽中,我使用readAll读取数据,然后执行一些工作并发送回复 但是,当我返回到run方法时,我需要继续向客户端发送歌曲数据更新

谁能告诉我我做得对吗

使用Qt,我通过继承qtcserver类来实现TCP服务器。在传入连接上,我创建一个新线程,一个新的Worker对象,然后将该对象移动到新线程并启动该线程。从这里开始,服务器不断侦听新的客户机,然后每个线程都处于对象工作线程的run方法中

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

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

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


发布代码能让这一点更清楚吗?

这个问题已经很老了,但也许它仍然有帮助

关于Qt中的线程:
许多人认为在Qt中进行并行处理,比如在.NET中,每次操作都需要另一个线程,在Qt中这是不必要的
在qt中,只有当您有阻塞代码(如计算大事件或等待syncron从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;
};
#包括
#包括
#包括
#包括
#包括
TcpServer类:公共QObject
{
Q_对象
公众:
TcpServer()
{
//处理新的连接
this->connect(&this->serverTcp,&qtcserver::newConnection,this,&TcpServer::handleClientConnect);
//初始化客户端刷新计时器
此->定时器设置间隔(1000);
this->connect(&this->timer,&QTimer::timeout,this,&TcpServer::handleClientUpdates);
这->timer.start();
}
bool startListen(qint16端口)
{
返回此->服务器TCP.listen(QHostAddress::Any,port);
}
专用插槽:
void handleClientConnect()
{
QTcpSocket*socketClient=*this->setConnectedClient.insert(this->serverTcp.nextPendingConnection());
this->connect(socketClient,&qtcsocket::disconnected,this,&TcpServer::handleClientDisconnect);
this->connect(socketClient,&qtcsocket::readyRead,this,&TcpServer::handleClientData);
}
void handleClientDisconnect()
{
此->设置连接的客户端。删除((QTcpSocket*)此->发送方();
}
void handleClientData()
{
QTcpSocket*socketSender=(QTcpSocket*)此->发件人();
//在这里处理客户端发送的数据
}
void handleClientUpdates()
{
//在这里构建您的更新数据
QByteArray baUpdateResponse=“测试”;
//向所有连接的客户端发送更新数据
foreach(QTcpSocket*socketClient,此->设置连接的客户端){
socketClient->write(baUpdateResponse);
}
}
私人:
qtcserver-serverTcp;
定时器;
QSet-setConnectedClients;
};

这个问题已经很老了,但也许它仍然有帮助

关于Qt中的线程:
许多人认为在Qt中进行并行处理,比如在.NET中,每次操作都需要另一个线程,在Qt中这是不必要的
在qt中,只有当您有阻塞代码(如计算大事件或等待syncron从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;
};
#包括
#包括
#包括
#包括
#包括
TcpServer类:公共QObject
{
Q_对象
公众:
TcpServer()
{
//处理新的连接
this->connect(&this->serverTcp,&qtcserver::newConnection,this,&TcpServer::handleClientConnect);
//初始化客户端刷新计时器
此->定时器设置间隔(1000);
this->connect(&this->timer,&QTimer::timeout,this,&TcpServer::handleClientUpdates);
这->timer.start();
}
bool startListen(qint16端口)
{
返回此->服务器TCP.listen(QHostAddress::Any,port);
}
专用插槽:
void handleClientConnect()
{
QTcpSocket*socketClient=*this->setConnectedClient.insert(this->serverTcp.nextPendingConnection());
this->connect(socketClient,&qtcsocket::disconnected,this,&TcpServer::handleClientDisconnect);
this->connect(socketClient,&qtcsocket::readyRead,this,&TcpServer::handleClientData);
}
void handleClientDisconnect()
{
此->设置连接的客户端。删除((QTcpSocket*)此->发送方();
}
void handleClientData()
{
QTcpSocket*socketSender=(QTcpSocket*)此->发件人();
//在这里处理客户端发送的数据
}
void handleClientUpdates()
{
//在这里构建您的更新数据
QByteArray baUpdateResponse=“测试”;