QT+多线程TCP服务器+进阶版
创始人
2025-01-10 09:35:39
0

        针对之前的服务器,如果子线程工作类里面需要使用socket发送消息,必须要使用信号与槽的方法, 先发送一个信号给父进程,父进程调用socket发送消息(原因是QT防止父子进程抢夺同一资源,因此直接规定父子进程不能使用同一资源,可能很片面,但至少针对socket这个类是这样的),因此,为了更好的使用多线程TCP服务器,下面介绍一种新的方法。

1、新建一个编译无错误的工程

2、在pro文件中加入network

3、新建两个类,一个Worker类继承QObject,一个TcpServer类继承QTcpServer

4、编辑服务器界面

5、给控件命名

6、查找本地有效的IPV4,并用combox控件显示

    QList ipAddressesList = QNetworkInterface::allAddresses();     for (int i = 0; i < ipAddressesList.size(); ++i) {         if (!ipAddressesList.at(i).isNull()//IP地址是否为NULL             && ipAddressesList.at(i).toIPv4Address() != 0//是否是IPV4地址             )         {             ui->IPComboBox->addItem(ipAddressesList.at(i).toString());         }     }

7、创建Server对象,绑定连接服务器按钮和创建代码

#include "tcpserver.h" TcpServer *tcpserver = NULL;//TcpServer这个是自定义的服务器类  void Widget::on_connectPushButton_clicked() {     if(ui->connectPushButton->text().contains("打开服务器"))     {         tcpserver = new TcpServer();           //实例化tcpserver对象         tcpserver->listen( QHostAddress(ui->IPComboBox->currentText()),ui->portLineEdit->text().toInt());//进行IP地址与端口的监听         ui->connectPushButton->setText("断开服务器");     }     else     {         tcpserver->close();         ui->connectPushButton->setText("打开服务器");     } } 

8、当客户端被连接时,TcpServer类会自己调用incomingConnection方法,然后我们需要重写这个方法,首先就是新建一个工作类,然后把套接字文件符传送过去,然后在构造函数初始化套接字

protected:     void incomingConnection(qintptr socketDescriptor) override; //当客户端连接时被调用。
void TcpServer::incomingConnection(qintptr socketDescriptor) {     QThread *thread = new QThread();     Worker *worker = new Worker(socketDescriptor);//socketDescriptor这个参数时套接字的描述符,用于生成套接字socket      connect(thread, &QThread::finished, thread, &QThread::deleteLater); //释放线程资源      worker->moveToThread(thread);     thread->start(); } 

 9、先修改工作类worker的构造函数,将套接字描述符加入

public:     explicit Worker(qintptr socketDescriptor,QObject *parent = nullptr);   Worker::Worker(qintptr socketDescriptor, QObject *parent)     : QObject{parent} {     m_socketDescriptor=socketDescriptor;      m_tcpsocket = new QTcpSocket(this);     m_tcpsocket->setSocketDescriptor(m_socketDescriptor); }

10、获取套接字之后开始处理读到的数据,在工作类中建立读信号和槽函数关系

public slots:     void onReadyRead();   connect(m_tcpsocket,&QTcpSocket::readyRead,this,&Worker::onReadyRead);   void Worker::onReadyRead() {     QByteArray data = m_tcpsocket->readAll();     m_tcpsocket->write("receive : "+data); } 

12、编译通过,且连接成功,可以将收到的消息发给服务器

 13、开始处理发送信息的消息,首先Widget界面有一个发送按钮,用于发送数据给客户端,代码实际操作时发送信号给工作类处理

signals:     void sendDataSignals(QString data);  void Widget::on_sendPushButton_clicked() {     emit sendDataSignals(ui->sendPlainTextEdit->toPlainText()); } 

我们如何让Widget和worker工作类产生联系,利用中间类TcpServer,我们先将sendDataSignals信号发送到TcpServer类中,利用connect信号转信号,然后等待TcpServer发送 sendDataSignals信号时绑定Worker类的槽函数进行发送数据

connect(this,&Widget::sendDataSignals,tcpserver,&TcpServer::sendDataSignals);
connect(this,&TcpServer::sendDataSignals,worker,&Worker::sendData_slots);
void Worker::sendData_slots(QString data) {      m_tcpsocket->write("send : "+data.toUtf8()+"\r\n"); }

 14、编译代码,运行成功,可以成功收发数据

15、当接收到数据后我们让其在网络数据接收窗口显示,采用信号与槽的机制

void Worker::onReadyRead() {     QByteArray data = m_tcpsocket->readAll();     m_tcpsocket->write("i am server,receive : "+data+"\r\n");     emit readDisplaySignals(QString::fromUtf8(data)); }
connect(worker,&Worker::readDisplaySignals,this,&TcpServer::readDisplaySignals);
connect(tcpserver,&TcpServer::readDisplaySignals,this,&Widget::readDataDisplay_slots);
void Widget::readDataDisplay_slots(QString data) {     QString str=ui->receivePlainTextEdit->toPlainText();//接收区之前的内容     QDateTime nowtime = QDateTime::currentDateTime();     str += "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] "+ "RX: ";//记录当前时间     str = str + data + "\r\n";//当前接收最新消息     ui->receivePlainTextEdit->setPlainText(str); }

16、测试成功

17、完整工程代码

链接:https://pan.baidu.com/s/1wqfFoLKSrARjDHIX0Y-diQ?
提取码:生日

相关内容

热门资讯

绝活儿辅助!广西老友玩老是输怎... 绝活儿辅助!广西老友玩老是输怎么办(辅助挂)都是真的有辅助app(讲解有挂)在进入广西老友玩老是输怎...
法门辅助!福建13水插件(辅助... 法门辅助!福建13水插件(辅助挂)一贯是有辅助技巧(有挂技术)1、许多玩家不知道福建13水插件辅助怎...
办法辅助!潮友会app下载官方... 办法辅助!潮友会app下载官方辅助器(辅助挂)真是真的是有辅助app(有挂教程)该软件可以轻松地帮助...
妙招辅助!邯郸胡乐挂辅助(辅助... 妙招辅助!邯郸胡乐挂辅助(辅助挂)好像存在有辅助插件(有挂方略)1、上手简单,内置详细流程视频教学,...
教程书辅助!乐酷辅助(辅助挂)... 教程书辅助!乐酷辅助(辅助挂)其实存在有辅助脚本(有挂细节)乐酷辅助能透视中分为三种模型:乐酷辅助模...
学习辅助!决战卡五星辅助(辅助... 学习辅助!决战卡五星辅助(辅助挂)本来真的是有辅助软件(有人有挂)学习辅助!决战卡五星辅助(辅助挂)...
绝活辅助!边锋嘉兴麻将辅助器(... 绝活辅助!边锋嘉兴麻将辅助器(辅助挂)真是真的有辅助神器(新版有挂)1、边锋嘉兴麻将辅助器公共底牌简...
举措辅助!枫叶辅助器(辅助挂)... 举措辅助!枫叶辅助器(辅助挂)本来存在有辅助技巧(竟然有挂)1、下载好枫叶辅助器正确养号方法之后点击...
讲义辅助!点我达辅助(辅助挂)... 讲义辅助!点我达辅助(辅助挂)一直存在有辅助技巧(有人有挂)1、点我达辅助辅助器安装包、点我达辅助辅...
模块辅助!威信茶馆有挂的吗(辅... 模块辅助!威信茶馆有挂的吗(辅助挂)一直真的是有辅助脚本(揭秘有挂)1、玩家可以在威信茶馆有挂的吗线...