在QT中使用多线程并发服务器(C++)

avatar
作者
猴君
阅读量:1

什么是多线程并发服务器?在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 。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!