Qt是一种跨平台的GUI应用程序框架,由于其可移植性、高效性及易用性,已经成为开发图形界面的首选开发工具之一。 Qt网络通信库提供了一组易用的API,支持开发基于TCP/UDP协议的网络应用,Qt服务器能够实现多客户端接入,本文将详细探讨如何实现这一功能。
一、Qt服务器实现多客户端接入的原理
在多客户端接入的情况下,服务器需要同时维护多个连接。服务器需要在一个线程中监听客户端的连接请求,并在接收到请求后为每个新连接分配一个唯一的套接字描述符,这个套接字描述符将用于服务器跟客户端进行通信。一旦服务器为客户端分配了一个套接字描述符,服务器就可以关闭主监听套接字,让这个新分配的套接字描述符去接收客户端的数据。
为了维护多个连接,服务器还需要保存一个客户端列表,每当服务器接收到一个新连接时,它会将新连接的套接字描述符放入到这个客户端列表中。服务器还需要监听每个客户端连接,当服务器接收到客户端数据时,服务器必须将这个客户端的套接字描述符跟这个数据包一起放入到队列中,然后下一个线程将从这个队列中取出数据并处理它。
二、Qt服务器实现多客户端接入的流程
下面是一个Qt服务器实现多客户端接入的基本流程:
1. 创建一个监听套接字,开始监听客户端连接请求。
2. 一旦有客户端请求连入,服务器接收连接请求并为其分配一个唯一的套接字描述符。
3. 将新分配的套接字描述符存储在客户端列表中,关闭主监听套接字。
4. 监听每个客户端连接,当服务器接收到客户端数据时,将数据包跟套接字描述符一起放入队列中。
5. 下一个线程从队列中取出数据并处理它。
6. 当一个客户端退出或因某种原因断开连接时,服务器需要从客户端列表中删除这个客户端对应的套接字描述符。
三、Qt服务器实现多客户端接入的代码实现
下面是一个简单的Qt服务器实现多客户端接入的代码示例,它实现了一个简单的回声(Echo)服务器,可以同时处理多个客户端的请求。
“`C++
#include
#include
class MyServer : public QObject
{
Q_OBJECT
public:
MyServer(QObject *parent = 0) : QObject(parent)
{
server = new QTcpServer(this);
connect(server, SIGNAL(newConnection()), this, SLOT(newConnection()));
if(server->listen(QHostAddress::Any, 8888))
{
qDebug()
}
else
{
qDebug()
}
}
signals:
void newData(QByteArray data, int socketDescriptor);
private slots:
void newConnection()
{
while(server->hasPendingConnections())
{
QTcpSocket *socket = server->nextPendingConnection();
int socketDescriptor = socket->socketDescriptor();
sockets[socketDescriptor] = socket;
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
}
}
void readyRead()
{
QTcpSocket *socket = (QTcpSocket*)sender();
emit newData(socket->readAll(), socket->socketDescriptor());
}
void disconnected()
{
QTcpSocket *socket = (QTcpSocket*)sender();
sockets.remove(socket->socketDescriptor());
}
public slots:
void send(QByteArray data, int socketDescriptor)
{
QTcpSocket *socket = sockets[socketDescriptor];
socket->write(data);
socket->flush();
}
private:
QTcpServer *server;
QHash sockets;
};
class Worker : public QObject
{
Q_OBJECT
public:
Worker(int socketDescriptor, QObject *parent = 0) : QObject(parent)
{
this->socketDescriptor = socketDescriptor;
socket = new QTcpSocket(this);
socket->setSocketDescriptor(socketDescriptor);
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
}
public slots:
void readyRead()
{
QByteArray data = socket->readAll();
emit newData(data, socketDescriptor);
}
void disconnected()
{
socket->deleteLater();
emit clientDisconnected(socketDescriptor);
}
void send(QByteArray data)
{
socket->write(data);
socket->flush();
}
signals:
void newData(QByteArray data, int socketDescriptor);
void clientDisconnected(int socketDescriptor);
private:
QTcpSocket *socket;
int socketDescriptor;
};
int mn(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyServer server;
QThreadPool pool;
pool.setMaxThreadCount(10);
QObject::connect(&server, SIGNAL(newData(QByteArray, int)), &pool, SLOT(start(Worker*)));
QObject::connect(&pool, &QThreadPool::started, [](){
qDebug()
});
QObject::connect(&server, &MyServer::newData, [](QByteArray data, int socketDescriptor){
qDebug()
server.send(data, socketDescriptor);
});
server.moveToThread(&a);
return a.exec();
}
“`
相关问题拓展阅读:
- qt中如何实现多线程?
qt中如何实现多线程?
你需要加深对网络编程猛袜镇基本概念的理解枝粗。
首先server端用于监听的是一个socket,每次有传入连接,就会有一个新的socket描述符产生,与客户端交互就是通过这个socket描述符。
如果使用 QTcpServer,你应该重写 incomingConnection() 函数,该函数可以拿到 socket 描述符,然后你使用自定义事件将这个socket描述符传递给一个线程,在这个线程中使用这个socket描述符来与客户端通信。这就是“通知+多线程”的服务器编程模型,Qt 中天生支持这种模型,很容易好姿实现。
QT线程是独立的类:
在QT中添加C++类,头文件引用#include ;类公开,这样写:
class XXXX:public QThread,类里面申明Q_OBJECT,直接写在里面。祥灶基signals: XXX();这是你的订阅事件名。private:void run();这是run函数;public: int cona=3;这是变量,一定要public。
cpp文件里引用头文件,run函数里面写方法:
void XXXX::run()
{
do
{
msleep(cona);
emit connec();
}while(true);
}
上面就是线程类了。现在我们在窗体中应用,先在头文件申明
头文件private: XXXX *thread1;XXXX *thread2;
构辩橡造函数中初始化他们
thread1=new XXXX();
thread1->谨谨cona=3;
QObject::connect(thread1,SIGNAL(connec()),this,SLOT(XXX信号1()));
thread2=new XXXX();
thread2->cona=4;
QObject::connect(thread2,SIGNAL(connec()),this,SLOT(XXX信号2()));
XXX信号1()是读A数据,XXX信号2()读B数据。
按钮1的信号槽里写方法同时进行每3秒读A、没4秒读B
thread1->start();
thread2->start();
要结束谁就用 xxxx->terminate();
看明白没?QT可不同与C++,你不熟悉编程环境,是很难理解的。
继承一个多线程类,在run里边写自己的函数,然后就行了
qt服务器接 多客户端的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于qt服务器接 多客户端,Qt服务器实现多客户端接入的技巧,qt中如何实现多线程?的信息别忘了在本站进行查找喔。