什么是多线程并发服务器?在QT里怎样利用多线程并发服务器呢?
多线程并发服务器是一种网络服务器计划,它可以大概同时处置惩罚多个客户端的哀求。在多线程服务器中,主线程负责监听和接受来自客户端的毗连哀求,每当有一个新的毗连哀求到来时,服务器就会创建一个新的线程来处置惩罚该毗连。这样,每个客户端都有一个专门的线程来为之服务,从而实现并发处置惩罚多个客户端哀求的目的。
下面是怎样在QT里利用多线程并发服务器的流程。
可以先看这个图理解一下。
重写incomingConnection()函数
起首在myserver.h里创建一个Myserver类继承QTcpServer,重写 incomingConnection();
并创建一个自定义信号。
myserver.h
- #ifndef MYSERVER_H
- #define MYSERVER_H
- #include<QTcpServer>
- class Myserver:public QTcpServer
- {
- Q_OBJECT
- public:
- Myserver(QObject *parent = 0);
- //重写,传递套接字描述(sd标志)
- void incomingConnection(qintptr socketDescriptor);
- ~Myserver();
- signals: //信号函数不需要实现
- void sig_sendsd(qintptr sd);
- };
- #endif // MYSERVER_H
复制代码
在myserver.c里实现重写的incomingConnection()函数,当有客户端毗连的时,会发送包含socket套接字描述符的信号sig_sendsd(socketDescriptor)(上面创建的信号)到主线程。(套接字描述符socketDescriptor很告急,在子线程里用来创建socket对象跟客户端进行通信)。
- #include "myserver.h"
- Myserver::Myserver(QObject *parent):QTcpServer(parent)
- {
- }
- void Myserver::incomingConnection(qintptr socketDescriptor)
- {
- //发送自定义信号给主线程(sd标志)
- emit sig_sendsd(socketDescriptor);
- }
- Myserver::~Myserver()
- {
- }
复制代码 创建子线程类
在socketthread.h里创建一个叫socketthread的子线程类用于处置惩罚每个客户端发来的信息。
- #ifndef SOCKETTHREAD_H
- #define SOCKETTHREAD_H
- #include<QThread>
- #include<QTcpSocket>
- class SocketThread:public QThread
- {
- Q_OBJECT
- public:
- SocketThread(qintptr sd);
- void run(); //重写run函数,执行线程
-
- ~SocketThread();
- private slots:
- void slot_read();
- void slot_disconnect();
- private:
- qintptr sd;
- QTcpSocket *socket;
-
- };
- #endif // SOCKETTHREAD_H
复制代码 在socketthread.c中run()函数中处置惩罚客户端发来的信息,以及发送信息到客户端。
- #include "socketthread.h"
- SocketThread::SocketThread(qintptr sd):sd(sd)
- {
-
- }
- void SocketThread::run()
- {
- socket=new QTcpSocket;
- socket->setSocketDescriptor(sd);
- connect(socket,SIGNAL(readyRead()),this,SLOT(slot_read()));
- connect(socket,SIGNAL(disconnected()),this,SLOT(slot_disconnect()));
- }
- void SocketThread::slot_read()
- {
- isRead=true;
- qDebug()<<"客服端来消息了";
- }
- void SocketThread::slot_disconnect()
- {
- qDebug()<<"客户端已断开";
- isRun=false;
- }
- SocketThread::~SocketThread()
- {
- qDebug()<<"子线程结束";
- }
复制代码 主线程(重点)
在主线程里创建myserver类对象,监听客户端,等待客户端毗连。当有客户端毗连时,myserver类对象会发出自定义信号sig_sendsd(qintptr),通过connect()函数,执行槽函数slot_recv_sd()。在槽函数里创建子线程类对象,在子线程类对象里创建socket套接字(上图),跟客户端通信。
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- initIp();
- server=new Myserver(this);
- server->listen(QHostAddress::Any,12345); //any所有地址 12345port
- //当有新的客户端连接,server对象会发出自定义信号
- connect(server,SIGNAL(sig_sendsd(qintptr)),this,SLOT(slot_recv_sd(qintptr)));
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- }
- void MainWindow::initIp() //获取本地ip地址
- {
- QString ip;
- QString hostName = QHostInfo::localHostName();
- QHostInfo info = QHostInfo::fromName(hostName);
- QList<QHostAddress> list=info.addresses();
- for(int i=0;i<list.size();i++)
- {
- //获取协议类型
- if(list[i].protocol()==QAbstractSocket::IPv4Protocol)
- {
- ip+="*";
- ip+=list[i].toString();
- }
- }
- ui->label_ip->setText(ip);
- }
- void MainWindow::slot_recv_sd(qintptr sd)
- {
- //创建子线程
- st=new SocketThread(sd);
- st->start();
-
- }
复制代码
最后的最后,感谢大家的支持,哀求各路豪杰豪杰多多打赏,多多关注,多多点赞,我是只发布高质量文章的 better-code 。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |