QT+网络调试助手+TCP服务器

news2025/1/16 9:01:20

一、UI界面设计

二、单线程 代码设计

1、 查找合法的本地地址,用于当作服务器的IP地址

#include <QThread>
#include <QTcpSocket>
#include <QNetworkInterface>
#include <QMessageBox>

QList<QHostAddress> 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());
        }
    }

2、打开服务器等待连接

void Widget::on_connectPushButton_clicked()
{
    if(ui->connectPushButton->text().contains("打开服务器"))
    {
        tcpserver = new QTcpServer(this);           //实例化tcpserver对象
        if(!tcpserver->listen( QHostAddress(ui->IPComboBox->currentText()),ui->portLineEdit->text().toInt())) //进行IP地址与端口的监听
        {
            QMessageBox::critical(this, "失败", "服务器启动失败");
        }else{
            QMessageBox::information(this, "成功", "服务器启动成功");
        }
        connect(tcpserver,&QTcpServer::newConnection,this,&Widget::onNewConnection_slot);
    
        ui->connectPushButton->setText("断开服务器");
    }
    else
    {
        tcpserver->close();
        ui->connectPushButton->setText("打开服务器");
    }
}

3、客户端连接,进入onNewConnection_slot槽函数

void Widget::onNewConnection_slot()
{
    clientSocket = tcpserver->nextPendingConnection();

    //如果客户端有数据向服务器发送过来,那么该套接字就会自动发送一个readyread信号
    connect(clientSocket, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);
}

4、显示接收数据

void Widget::readyRead_slot()
{
    QString msg = ui->receivePlainTextEdit->toPlainText() +"\r\n" + QString::fromLocal8Bit(clientSocket->readAll());
    ui->receivePlainTextEdit->setPlainText(msg);
}

5、发送数据

void Widget::on_sendPushButton_clicked()
{
    clientSocket->write(ui->sendPlainTextEdit->toPlainText().toUtf8());
}

 完成以上功能之后我们发现如何客户端断开连接后就不能在连接,原因在于服务器只对一个连接对象进行处理,因此,我们需要使用线程的方法去处理客户端的连接。

三、多线程 代码设计

1、新建一个工作类Worker继承于QObject

2、在主线程Widget的onNewConnection_slot函数里面实现多个服务器连接,代码的作用就是将工作累反倒线程里面调用

void Widget::onNewConnection_slot()
{
    while(tcpserver->hasPendingConnections())
    {
        QTcpSocket  *clientSocket = tcpserver->nextPendingConnection();     //获取通信套接字
        QThread     *thread       = new QThread(this);                      //创建子线程
        Worker      *worker       = new Worker(clientSocket);                 //创建工作对象

        connect(worker,&Worker::sendDataSignal,clientSocket,[clientSocket](const QByteArray &data){
            clientSocket->write(data);
        });

        worker->moveToThread(thread);   //将工作对象放进子线程运行
        thread->start();                //子线程开始运行
    }
}

3、工作类中需要接收客户端的句柄,因此需要修改工作类的构造函数

public:
    explicit Worker(QTcpSocket *socket,QObject *parent = nullptr);


Worker::Worker(QTcpSocket *socket,QObject *parent)
    : QObject{parent}
{
    tcpsocket = socket;

    connect(tcpsocket,&QTcpSocket::readyRead,this,&Worker::onReadyRead);
    connect(tcpsocket,&QTcpSocket::disconnected,this,&Worker::onDisconnect);
}

4、然后创建槽函数,切记:工作类需要调用write方法时,必须使用信号与槽的机制

signals:
    void sendDataSignal(QByteArray data);



void Worker::onDisconnect()
{
    qDebug()<<"连接断开";
}

/*tcpsocket是单线程的,所以子线程中不能调用tcpsocket的wirte方法,需要放在父线程中调用
子线程接收数据进行处理,给客户端发送相同的信息*/
void Worker::onReadyRead()
{
    QByteArray str=tcpsocket->readAll();
    qDebug()<<QString::fromLocal8Bit(str);
    emit sendDataSignal(str);
}

四、结果

可以实现多个客户端进行连接,之所以UI界面没有反应,因为没有写对应的代码

五、完整工程

链接:https://pan.baidu.com/s/1gZZ9HL_XQZIae2fhoWVjcA?pwd=8888 
提取码:8888

六、等比例放大界面

      DEVMODE NewDevMode;
      EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, &NewDevMode);//获取屏幕设置中的分辨率
      qDebug()<<NewDevMode.dmPelsWidth;//屏幕分辨率宽
      qDebug()<<NewDevMode.dmPelsHeight;//屏幕分辨率高

      qreal  scale = NewDevMode.dmPelsWidth * NewDevMode.dmPelsHeight / 1080.0 / 1920.0;			//当前设置的屏幕宽度
      qDebug()<<scale;
      qputenv("QT_SCALE_FACTOR", QString::number(scale).toLatin1());

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

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

相关文章

华为机考入门python3--(23)牛客23- 删除字符串中出现次数最少的字符

分类&#xff1a;字符串 知识点&#xff1a; 访问字典中keychar的值&#xff0c;不存在则返回0 my_dict.get(char, 0) 字典的所有值 my_dict.value() 列表中的最小值 min(my_list) 题目来自【牛客】 import sysdef delete_min_freq_char(s):# 计算字母出现的频次…

Arduino控制继电器,制作智能浇水系统

所需硬件材料 Arduino模块、继电器、直流电机、3-6v电池&#xff08;这个是必须的&#xff0c;电机不能直接接在arduino的5v引脚上&#xff0c;会引起电压不足&#xff09;、杜邦线 实现效果&#xff1a; 电机转动一秒停一秒 将硬件连接如下&#xff1a; 将电机连接到继电…

(MATLAB)安装指南

参考链接&#xff1a;MATLAB2019a安装教程&#xff08;避坑版&#xff09;

应用层协议——HTTP协议

1. 认识HTTP协议 HTTP&#xff08;Hyper Text Transfer Protocol&#xff09;协议又叫做超文本传输协议&#xff0c;是一个简单的请求-响应协议&#xff0c;HTTP通常运行在TCP之上。 超文本的意思就是超越普通的文本&#xff0c;http允许传送文字&#xff0c;图片&#xff0c…

PostgreSQL连接拒绝如何解决和排查?

1. 服务器未运行 解决方案&#xff1a;确保 PostgreSQL 服务已启动。在 Linux 上&#xff0c;你可以使用如下命令来检查服务状态&#xff1a;sudo systemctl status postgresql如果服务未运行&#xff0c;使用以下命令启动它&#xff1a;sudo systemctl start postgresql2. Po…

基于Springboot+Vue的Java项目-旅游网站系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

shell脚本编写-测试同一网段内主机是否在线

除了可以使用ansible自动化运维工具判断主机是否在线以外&#xff0c;还可以通过编写Shell脚本来实现。 1、编写脚本 #! /bin/bash #测试192.168.81.0/24网段中哪些主机处于开机状态&#xff0c;哪些主机处于关机状态# #方法一&#xff1a;使用for循环判断 # for i in {1..25…

亿发解密:数据中台管理系统,引领企业数字化转型的智能数据体系

在当今数字化时代&#xff0c;数据已成为企业发展的关键驱动力。为了更好地利用数据&#xff0c;提升业务水平&#xff0c;企业需要建立一套完备的数据管理体系&#xff0c;而数据中台便应运而生。 什么是数据中台 数据中台是集方法论、组织和工具于一体的智能大数据体系。它…

通信录的动态版本

一. 增加需求 在学习了动态开辟内存之后 我们对于通讯录产生了新的需求 要求我们做出一个动态增长的版本 即 随着我们储存联系人的增加 储存的空间增加 要求 &#xff1a; 1 初始空间为3 2 每次达到上限之后 扩容两个内存 二. 动手实施 我们首先要创建一个结构体 结构体…

计算图:深度学习中的链式求导与反向传播引擎

在深度学习的世界中&#xff0c;计算图扮演着至关重要的角色。它不仅是数学计算的图形化表示&#xff0c;更是链式求导与反向传播算法的核心。本文将深入探讨计算图的基本概念、与链式求导的紧密关系及其在反向传播中的应用&#xff0c;旨在为读者提供一个全面而深入的理解。 计…

Springboot项目学习之各组件的用法和逻辑结构

1.Controller层&#xff08;Controller&#xff09;&#xff1a; 也称为前端控制器或请求处理器&#xff0c;它是项目与用户交互的入口。Controller接收HTTP请求&#xff0c;解析请求参数&#xff0c;调用Service层处理业务逻辑&#xff0c;并返回响应给客户端。 Controller通…

Python实现txt转Excel(坐标)

import pandas as pddef txt_to_excel(txt_file, excel_file):# 读取 txt 文件with open(txt_file, r) as f:lines f.readlines()# 将每行数据分割成多个单元格data []for line in lines:row line.strip().split( )data.append(row)# 将数据保存到 Excel 文件df pd.DataFra…

阿里巴巴alibaba国际站API接口:商品详情和关键词搜索商品列表

阿里巴巴国际站&#xff08;Alibaba.com&#xff09;提供了API接口供开发者使用&#xff0c;以实现与平台的数据交互。然而&#xff0c;由于API的详细内容和调用方式可能会随着时间和平台更新而发生变化&#xff0c;以下是一个概述和一般性的指导&#xff0c;关于如何使用阿里巴…

代码随想录第52天|300.最长递增子序列 718. 最长重复子数组

300.最长递增子序列 300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; 代码随想录 (programmercarl.com) 动态规划之子序列问题&#xff0c;元素不连续&#xff01;| LeetCode&#xff1a;300.最长递增子序列_哔哩哔哩_bilibili 给你一个整数数组 nums &#xff0…

xmind的13个快捷方式

1.新建导图 CtrlshiftN 2.编辑文字 空格键 3.插入图片 Ctrli 4. 插入主题 Enter键 5. 插入主题之前 ShiftEnter键 6. 插入子主题 Tab键 7. 放大导图 “Ctrl”“” 8. 缩小导图 “Ctrl”“-” 9. 复制 CtrlInsert 10. 粘贴 Shift Insert 11. 剪切 ShiftDelete 12. 截图 F7 13. 保…

神经网络怎么把隐含层变量融合到损失函数中?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

Unity初级---初识生命周期

1. Awake() &#xff1a;唤醒函数&#xff0c;最先执行的函数&#xff0c;只执行一次&#xff0c;当脚本文件挂载的对象被激活时调用 2. OnEnable() &#xff0c;OnDisable()&#xff1a;当脚本启用和禁用时触发&#xff0c;可执行多次&#xff0c;触发的前提是脚本挂载的对象…

SolidWorks进行热力学有限元分析一、模型建立

1.话不多说按照我的操作来 2.这一步鼠标移到中心点直接拉就行 3.这里选单位&#xff0c;继续按照操作来 4.选中这个边&#xff0c;直接拉&#xff0c;输入尺寸后确定&#xff0c;其他边同理 5.鼠标右键设置厚度 6.右键零件&#xff0c;然后编辑材料&#xff0c;给他赋予你需要的…

纯血鸿蒙APP实战开发——折叠屏扫描二维码方案

折叠屏扫描二维码方案 介绍 本示例介绍使用自定义界面扫码能力在折叠屏设备中实现折叠态切换适配。自定义界面扫码使用系统能力customScan&#xff0c;其提供相机流的初始化、启动扫码、识别、停止扫码、释放相机流资源等能力。折叠屏折叠状态通过监听display的foldStatusCha…

【论文阅读】Fuzz4All: Universal Fuzzing with Large Language Models

文章目录 摘要一、介绍二、Fuzz4All的方法2.1、自动提示2.1.1、自动提示算法2.1.2、自动提示的例子2.1.3、与现有自动提示技术的比较 2.2、fuzzing循环2.2.1、模糊循环算法2.2.2、Oracle 三、实验设计3.1、实现3.2、被测系统和baseline3.3、实验设置以及评估指标 四、结果分析4…