QT网络调试助手

QT网络调试助手

  •  1.开发流程
  •  2.QTtcp服务器
    •    1.1 服务端数据读取
    •    1.2 服务端发送数据-所有客户端
    •    1.3 服务端自动刷新ip地址
    •    1.4 服务端检测客户端断开状态
    •    1.5 服务端发送数据-指定特定客户端发送数据
    •    1.6 服务端停止监听和断开
  •  3.QTtcp客户端

 1.开发流程

在这里插入图片描述

 2.QTtcp服务器

	1.添加网络访问权限QT += network2.创建一个新对象server = new QTcpServer(this);3.当监听按钮按下后开始监听
void Widget::on_btnListen_clicked()
{//2.监听:bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)   8888-15000//QHostAddress addr("192.168.0.101");port = ui->lineEditPort->text().toUInt();if(!server->listen(QHostAddress(ui->comboBoxAddr->currentText()),port)){    //自动检测ip地址:QHostAddress::AnyQMessageBox msgBox;msgBox.setWindowTitle("监听失败");msgBox.setText("端口号被占用");msgBox.exec();return;}ui->btnListen->setEnabled(false);ui->btnLineOut->setEnabled(true);ui->btnStopListen->setEnabled(true);ui->btnSend->setEnabled(true);//qDebug() << QHostAddress(ui->comboBoxAddr->currentText());
}4.监听到新的newConnection()信号后对新的连接进行处理connect(server,SIGNAL(newConnection()),this,SLOT(on_newClient_connect()));void Widget::on_newClient_connect()
{//所有的数据操作都是TcpSocket进行//bool QTcpServer::hasPendingConnections() const    有新的连接返回Trueif(server->hasPendingConnections()){//QTcpSocket *QTcpServer::nextPendingConnection()   返回下个连接来的connectQTcpSocket *connection = server->nextPendingConnection(); //获得到的客户端连接信息都在connection里,并将信息也保存在server中qDebug() << "client addr: " <<connection->peerAddress().toString() <<",port: " << connection->peerPort();ui->textEditRev->insertPlainText("客户端地址:" + connection->peerAddress().toString()+"\n客户端端口号:" + QString::number(connection->peerPort())+ "\n");connect(connection,SIGNAL(readyRead()),this,SLOT(on_readyRead_handler()));//断开后信号:void QAbstractSocket::disconnected()//connect(connection,SIGNAL(disconnected()),this,SLOT(mdisconnected()));//void QAbstractSocket::stateChanged(QAbstractSocket::SocketState socketState)connect(connection,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(mstateChanged(QAbstractSocket::SocketState)));ui->comboBoxChildren->addItem(QString::number(connection->peerPort()));ui->comboBoxChildren->setCurrentText(QString::number(connection->peerPort()));if(!ui->btnSend->isEnabled()){ui->btnSend->setEnabled(true);}}
}

   1.1 服务端数据读取

	connect(connection,SIGNAL(readyRead()),this,SLOT(on_readyRead_handler())void Widget::on_readyRead_handler()
{QTcpSocket *tmpSocket = qobject_cast<QTcpSocket *>(sender());  //获得信号的发出者QByteArray RevData = tmpSocket->readAll();ui->textEditRev->insertPlainText("客户端:" + RevData + '\n');ui->textEditRev->moveCursor(QTextCursor::End);  //将读取光标移动至尾部ui->textEditRev->ensureCursorVisible(); //确定光标可见
}

   1.2 服务端发送数据-所有客户端

on_newClient_connect()中QTcpSocket *connection = server->nextPendingConnection(); 会将信息也保存在server中,server是全局变量,对server来说,每一个socket都是server的child所以通过其父类QObject的FindChildren可以找到所有的socket
}void Widget::on_btnSend_clicked()
{//QTcpSocket *connection = server->nextPendingConnection(); //获得到的客户端连接信息都在connection里,并将信息也保存在server中QList<QTcpSocket *> tcpSocketClients = server->findChildren<QTcpSocket *>();for(QTcpSocket *tmp : tcpSocketClients){//ui->textEditSend->toPlainText().toStdString().c_str()--先将QString转换成标准的c++字符串,再转换成const char*型tmp->write(ui->textEditSend->toPlainText().toStdString().c_str());}
}

   1.3 服务端自动刷新ip地址

	QNetworkInterfaceQList<QHostAddress> QNetworkInterface::allAddresses()//QList<QHostAddress> QNetworkInterface::allAddresses()QList<QHostAddress> address = QNetworkInterface::allAddresses();    //获取地址for(QHostAddress tmp : address){if(tmp.protocol() == QAbstractSocket::IPv4Protocol) //将ipv4的地址刷入comboxui->comboBoxAddr->addItem(tmp.toString());}

   1.4 服务端检测客户端断开状态

注:每次一断开之后必须清空通道即deleteLater();否则server中会一直保留该通道1.信号:void QAbstractSocket::disconnected()	connect(connection,SIGNAL(disconnected()),this,SLOT(mdisconnected()));void Widget::mdisconnected()
{QTcpSocket *tmpSocket = qobject_cast<QTcpSocket *>(sender());  //获得信号的发出者qDebug() << "client Out";ui->textEditRev->insertPlainText("客户端断开! ");tmpSocket->deleteLater();}2.信号:void QAbstractSocket::stateChanged(QAbstractSocket::SocketState socketState)void Widget::mstateChanged(QAbstractSocket::SocketState socketState)
{QTcpSocket *tmpSocket = qobject_cast<QTcpSocket *>(sender());  //获得信号的发出者switch(socketState){case QAbstractSocket::ClosingState://case QAbstractSocket::UnconnectedState:ui->textEditRev->insertPlainText("客户端断开! ");tmpSocket->deleteLater();break;}
}

   1.5 服务端发送数据-指定特定客户端发送数据

	1.因为ComboBox不提供鼠标点击刷新事件,因此需要重写ComboBox的鼠标点击事件和信号void MyComboBox::mousePressEvent(QMouseEvent *e)
{if(e->button() == Qt::LeftButton){emit ComboBox_clicked();}QComboBox::mousePressEvent(e);
}2.将控件提升为MyComboBox,并绑定信号与槽connect(ui->comboBoxChildren,&MyComboBox::ComboBox_clicked,this,&Widget::MyComboBox_refresh);//刷新ComboBox控件内容---为ComboBox添加接入的端口void Widget::MyComboBox_refresh()
{ui->comboBoxChildren->clear();QList<QTcpSocket *> tcpSocketClients = server->findChildren<QTcpSocket *>();for(QTcpSocket *tmp : tcpSocketClients){ui->comboBoxChildren->addItem(QString::number(tmp->peerPort()));}ui->comboBoxChildren->addItem("all");
}2.重写发送
void Widget::on_btnSend_clicked()
{//QTcpSocket *connection = server->nextPendingConnection(); //获得到的客户端连接信息都在connection里,并将信息也保存在server中QList<QTcpSocket *> tcpSocketClients = server->findChildren<QTcpSocket *>();if(tcpSocketClients.isEmpty()){QMessageBox msg;msg.setText("当前无连接");msg.exec();ui->btnSend->setEnabled(false);return ;}if(ui->comboBoxChildren->currentText() != "all"){QString currentname = ui->comboBoxChildren->currentText();for(QTcpSocket *tmp :tcpSocketClients){if(QString::number(tmp->peerPort()) == currentname){tmp->write(ui->textEditSend->toPlainText().toStdString().c_str());}}}else{for(QTcpSocket *tmp : tcpSocketClients){//ui->textEditSend->toPlainText().toStdString().c_str()--先将QString转换成标准的c++字符串,再转换成const char*型tmp->write(ui->textEditSend->toPlainText().toStdString().c_str());}}
}

   1.6 服务端停止监听和断开

void Widget::on_btnStopListen_clicked()
{QList<QTcpSocket *> tcpSocketClients = server->findChildren<QTcpSocket *>();for(QTcpSocket *tmp : tcpSocketClients){tmp->close();}server->close();ui->btnListen->setEnabled(true);ui->btnLineOut->setEnabled(false);ui->btnStopListen->setEnabled(false);
}void Widget::on_btnLineOut_clicked()
{on_btnStopListen_clicked();delete server;this->close();
}

 3.QTtcp客户端

	客户端逻辑相对简单直接上代码:
void Widget::on_pushButtonConnect_clicked()
{//void connectToHost(const QHostAddress &address, quint16 port, QIODevice::OpenMode openMode = ReadWrite)client->connectToHost(ui->lineEditIp->text(),ui->lineEditPort->text().toUInt());	//连接服务器timer = new QTimer(this);timer->setSingleShot(1);timer->setInterval(5000);connect(timer,SIGNAL(timeout()),this,SLOT(onTimerOut()));connect(client,SIGNAL(connected()),this,SLOT(onConnected()));//void QAbstractSocket::error(QAbstractSocket::SocketError socketError)connect(client,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(onError(QAbstractSocket::SocketError)));this->setEnabled(false);timer->start();
}void Widget::mread_data_from_server()
{setInsertColor(Qt::black, "服务器:"+ client->readAll());
}void Widget::on_btnSend_clicked()
{QByteArray sendData = ui->textEditSend->toPlainText().toStdString().c_str();client->write(sendData);setInsertColor(Qt::red,"客户端:" + sendData);
}void Widget::on_pushButtonOut_clicked()
{client->close();ui->textEditRev->append("断开连接\n");ui->pushButtonConnect->setEnabled(true);ui->lineEditIp->setEnabled(true);ui->lineEditPort->setEnabled(true);ui->pushButtonOut->setEnabled(false);ui->btnSend->setEnabled(false);
}void Widget::onConnected()
{timer->stop();this->setEnabled(true);ui->textEditRev->insertPlainText("连接成功\n");ui->pushButtonConnect->setEnabled(false);ui->lineEditIp->setEnabled(false);ui->lineEditPort->setEnabled(false);ui->pushButtonOut->setEnabled(true);ui->btnSend->setEnabled(true);
}void Widget::onError(QAbstractSocket::SocketError error)
{this->setEnabled(true);on_pushButtonOut_clicked();
}void Widget::onTimerOut()
{ui->textEditRev->insertPlainText("连接超时!");client->abort(); //放弃当前连接this->setEnabled(true);}void Widget::setInsertColor(Qt::GlobalColor color, QString str)
{QTextCursor cursor = ui->textEditRev->textCursor();QTextCharFormat format;QBrush brush(color);format.setForeground(brush);cursor.setCharFormat(format);cursor.insertText(str+'\n');ui->textEditRev->moveCursor(QTextCursor::End);  //将光标移动至尾部ui->textEditRev->ensureCursorVisible(); //确定光标可见
}

链接:https://pan.baidu.com/s/1uI_bhvufjcuW1R6CrR9P7g
提取码:3urt
–来自百度网盘超级会员V5的分享

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/789202.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mathematical-expression(MAE)数学表达式 数学函数 解析编译库,有效的快速和简单易用的数学和计算机的编译器

数学表达式 Switch to English Document 介绍 本框架是一种针对数学公式解析的有效工具&#xff0c;能够解析包含嵌套函数&#xff0c;包含函数&#xff0c;数列步长累加等数学公式&#xff0c;返回值是一个数值的结果对象&#xff0c;同时也可以进行比较运算的操作&#xf…

为什么蓝牙信道探测将引领高精度定位服务?

从蓝牙耳机到智能家居设备&#xff0c;蓝牙技术因其成熟的音频流和数据传输功能已成为我们生活中的一部分。一项新技术——蓝牙信道探测&#xff08;Bluetooth Channel Sounding&#xff09;正向高精度定位服务市场迈进。 本文信驰达&#xff08;RF-star&#xff09;将介绍蓝牙…

数码论坛系统的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)电子科技数码爱好者交流信息新闻畅聊讨论评价

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读300套最新项目持续更新中..... 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含ja…

使用TCP协议就一定零丢包了吗?

简述数据包发送流程 为了简化模型&#xff0c;我们把中间的服务器给省略掉&#xff0c;假设这是个端到端的通信。且为了保证消息的可靠性&#xff0c;它们之间用的是TCP协议进行通信。 为了发送数据包&#xff0c;两端首先会通过三次握手&#xff0c;建立TCP连接。 一个数据包&…

Unity | Shader基础知识(第十一集:什么是Normal Map法线贴图)

目录 前言 一、图片是否有法线贴图的视觉区别 二、有视觉区别的原因 三、法线贴图的作用 四、信息是如何存进去的 五、自己写一个Shader用到法线贴图 六、注意事项 七、作者的话 前言 本小节会给大家解释&#xff0c;什么是法线贴图&#xff1f;为什么法线贴图会产生深…

Spring源码分析(BeanFactory)

文章目录 Spring源码分析&#xff08;BeanFactory&#xff09;一、BeanFactory二、ApplicationContext 的父系1、HierarchicalBeanFactory2、ListableBeanFactory3、EnvironmentCapable4、ApplicationEventPublisher5、MessageSource6、ResourcePatternResolver 三、Applicatio…

了解这些技术:Flutter应用顺利登陆iOS平台的步骤与方法

引言 &#x1f680; Flutter作为一种跨平台的移动应用程序开发框架&#xff0c;为开发者提供了便利&#xff0c;使他们能够通过单一的代码库构建出高性能、高保真度的应用程序&#xff0c;同时支持Android和iOS两个平台。然而&#xff0c;完成Flutter应用程序的开发只是第一步…

【鹅厂摸鱼日记(一)】(工作篇)认识八大技术架构

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:重生之我在鹅厂摸鱼⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多知识   &#x1f51d;&#x1f51d; 认识八大架构 1. 前言2. 架构简介&…

【Spring】SpringBoot整合ShardingSphere并实现多线程分批插入10000条数据(进行分库分表操作)。

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 一、ShardingSphere简介 ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈&#xff0c;它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar&#xff08;计划中&#xff09;这3款相互独立的产品组成…

【2024 信息素养大赛c++模拟题】算法创意实践挑战赛(基于 C++)

一、 比赛简介 国务院发布《国务院关于印发新一代人工智能发展规划的通 知》&#xff0c;明确实施全民智能教育项目。教育部印发《2019 年教育信息 化和网络安全工作要点》&#xff0c;推动在中小学阶段设置人工智能相关课 程&#xff0c;逐步推广编程教育。本赛项是在贯彻…

Linux学习笔记————C 语言版 LED 灯实验

这里写目录标题 一、实验程序编写二、 汇编部分实验程序编写三、C 语言部分实验程序编写四、编译下载验证 汇编 LED 灯实验中&#xff0c;我们讲解了如何使用汇编来编写 LED 灯驱动&#xff0c;实际工作中是很少用到汇编去写嵌入式驱动的&#xff0c;毕竟汇编太难&#xff0c;而…

用于HUD平视显示器的控制芯片:S2D13V40

一款利用汽车抬头显示技术用于HUD平视显示器的控制芯片:S2D13V40。HUD的全称是Head Up Display&#xff0c;即平视显示器&#xff0c;以前应用于军用飞机上&#xff0c;旨在降低飞行员需要低头查看仪表的频率。起初&#xff0c;HUD通过光学原理&#xff0c;将驾驶相关的信息投射…

1.Git是用来干嘛的

本文章学习于【GeekHour】一小时Git教程&#xff0c;来自bilibili Git就是一个文件管理系统&#xff0c;这样说吧&#xff0c;当多个人同时在操作一个文件的同时&#xff0c;很容易造成紊乱&#xff0c;git就是保证文件不紊乱产生的 包括集中式管理系统和分布式管理系统 听懂…

00 - Logic Circuit 简介 -- 与或非门

---- 整理自B站UP主 踌躇月光 的视频 1. Logic Circuit Logic Circuit 下载地址 界面如下&#xff0c;实际使用可下载体验 2. 与或非门

HTML常用的图片标签和超链接标签

目录 一.常用的图片标签和超链接标签&#xff1a; 1.超链接标签&#xff1a; 前言: 超链接的使用&#xff1a; target属性: 1)鼠标样式&#xff1a; 2)颜色及下划线: 总结: 2.图片标签&#xff1a; 前言: img的使用: 设置图片&#xff1a; 1.设置宽度和高度: 2.HTM…

排序算法-归并排序

Leetcode链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 归并&#xff1a;将原始数组划分为若干个子数组&#xff0c;然后将这些子数组分别排序&#xff0c;最后再将已排序的子数组合并成一个有序的数组。是一种分治思想 思路&#xff1a; 1.分 2.治 3.怎么治 …

力扣1047. 删除字符串中的所有相邻重复项

思路&#xff1a;消消乐的感觉&#xff0c;就先想到栈&#xff1b;用一个栈存放遍历过的元素&#xff0c;和遍历中的下一个元素相比&#xff0c;相同则出栈&#xff0c;不同则入栈&#xff0c;最终栈内剩余的就是不相同的元素。 class Solution {public String removeDuplicat…

C语言第三十九弹---预处理(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 预处理 1、预定义符号 2、#define定义常量 3、#define定义宏 4、带有副作用的宏参数 5、宏替换的规则 6、宏和函数的对比 总结 在C语言中&#xff0c;预处…

【C++】多态的原理

目录 一、虚函数表 1、虚函数表的定义 2、虚函数表特性 3、虚表的打印 二、多态的原理 三、多态的相关问题 1、指针偏移问题 2、输出的程序是什么&#xff1f; 3、输出的程序是什么&#xff1f; 【前言】 上一篇我们学习了多态的基础知识&#xff0c;这一篇我将带着大…

HarmonyOS 应用开发之通过数据管理服务实现数据共享静默访问

场景介绍 典型跨应用访问数据的用户场景下&#xff0c;数据提供方会存在多次被拉起的情况。 为了降低数据提供方拉起次数&#xff0c;提高访问速度&#xff0c;OpenHarmony提供了一种不拉起数据提供方直接访问数据库的方式&#xff0c;即静默数据访问。 静默数据访问通过数据…