当前位置: 首页 > news >正文

Qt项目实现对西门子PLC的读写操作(snap7)——C++

实际项目中需要用到对西门子PLC进行通讯,故进行记录,方便后续回顾复习
实现功能:
①PLC连接与断开
②往PLC指定位置读写操作(bit、real、string)

PLC中的real相当于C++中的float,4字节,32bit

1,下载西门子对应的SDK

在这里插入图片描述

2,拿到snap7.dllsnap7.libsnap7.hsnap7.cpp

snap7-full-1.4.2\examples\cpp
snap7-full-1.4.2\examples\cpp\win64

snap7.h和snap7.cpp

知道snap7.h位置啦
知道snap7.cpp位置啦

在这里插入图片描述
在这里插入图片描述

3,在snap7-full-1.4.2\rich-demos\x86_64-win64\bin下有客户端和服务器可以进行本地模拟测试,这里需要使用服务器进行模拟PLC

在这里插入图片描述

这里大概讲解下软件如何使用

在这里插入图片描述
在这里插入图片描述

4,创建Qt项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
运行下看看效果,没问题
在这里插入图片描述
我个人喜欢手动创建文件夹和手动创建属性表
src存放snap7.cpp、include存放snap7.h、snap\lib文件夹存放snap7.lib、x64\解决方案平台\和exe同级路径下存放snap7.dll
在这里插入图片描述

配置snap7的属性表
在这里插入图片描述

VC++目录\库目录,选择对应的snap7.lib所在路径
在这里插入图片描述

链接器\输入\附加依赖项,填入具体的lib名称,snap7.lib
在这里插入图片描述

ok,运行项目,会发现snap7.cppmain.cppPLC_Demo_Qt.cpp报错,找不到头文件,我们改一下即可
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

再次运行,项目没问题,UI出来了就行
在这里插入图片描述

5,项目结构分析

我们主要在PLC_Demo_Qt.hPLC_Demo_Qt.cpp下调用snap7.hsnap7.cpp实现对应的读写操作功能
连接、断开、读写等操作均在PLC_Demo_Qt.hPLC_Demo_Qt.cpp声明和实现
在这里插入图片描述
UI布局也比较简单
在这里插入图片描述

6,代码实现

①main.cpp

#include "include/PLC_Demo_Qt.h"
#include <QtWidgets/QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);PLC_Demo_Qt w;w.show();return a.exec();
}

②PLC_Demo_Qt.h

1,QMutex mutex_{QMutex::Recursive};因为在访问PLC的时候可能会产生冲突,故加上了Qt的递归锁
2,std::shared_ptr<TS7Client> client_;snap的客户端智能指针,用它读写PLC
3,SetBit是设置具体DB的Index的具体bit位的值,因为是bit,故处理的是一个字节中的某个位
4,isLittleEndian()判断PLC是大端模式还是小端模式
大端模式:数据的高位字节存放在内存的低地址处,低位字节存放在内存的高地址处。符合人类正常的数字读写顺序,比如对于一个多字节的数值,从左到右(低地址到高地址)依次是高位到低位,就像我们平时书写数字一样。
小端模式:数据的低位字节存放在内存的低地址处,高位字节存放在内存的高地址处。对于计算机处理器来说,小端模式可能更便于处理,因为许多处理器(如 x86 架构的处理器)采用小端模式,在进行数据操作时,从低地址开始读取低位字节可能更符合处理器的设计逻辑。
5,SetValue和GetValue这里我进行了函数重载,应该比较好理解

#pragma once
#include <QMutex>
#include <QtWidgets/QMainWindow>
#include <memory>#include "PLC_Demo_Qt.h"
#include "include/snap7.h"
#include "ui_PLC_Demo_Qt.h"class PLC_Demo_Qt : public QMainWindow {Q_OBJECTQMutex mutex_{QMutex::Recursive};std::shared_ptr<TS7Client> client_;public:PLC_Demo_Qt(QWidget* parent = nullptr);~PLC_Demo_Qt();[[nodiscard]] bool Connect();[[nodiscard]] bool Disconnect();[[nodiscard]] bool IsConnected();[[nodiscard]] void SetBit(unsigned char& byte, const int bit_index,const bool value);[[nodiscard]] bool GetBit(const unsigned char& byte, const int bit_index);[[nodiscard]] bool isLittleEndian();[[nodiscard]] bool SetValue(const int db, const int index, const int bit, bool value);[[nodiscard]] bool GetValue(const int db, const int index, const int bit, bool& is_set);[[nodiscard]] bool SetValue(const int db, const int index, const int bit, float f_value);[[nodiscard]] bool GetValue(const int db, const int index, const int bit, float& f_value);[[nodiscard]] bool SetValue(const int db, const int index, const int bit, const int max_length, QString s_value);[[nodiscard]] bool GetValue(const int db, const int index, const int bit, const int max_length, QString& s_value);private:Ui::PLC_Demo_QtClass ui;};

③PLC_Demo_Qt.cpp

1,client_->DBRead(db, index, 1, &buffer);读取某一位,这里的1表示几个字节的意思,因为要处理某个位,默认应该是一个字节,所以这里就按一个字节进行处理了
2,client_->DBRead(db, index, 4, buffer);读取real数据类型,相当于float,4字节,故第三个参数是4
3,client_->DBRead(db, index, max_length + 2, buffer);读取String类型,需要注意的是,字符第一个字节记录的是字符串总长度,第二个字节记录的是字符串的有效长度,之后才是具体的内容,故要进行+2处理
4,其他的应该没啥了,也比较好理解

#include "include\PLC_Demo_Qt.h"
#include <iostream>#include <QDebug>PLC_Demo_Qt::PLC_Demo_Qt(QWidget* parent) : QMainWindow(parent),
client_(std::make_shared<TS7Client>())
{ui.setupUi(this);connect(ui.pushButton_connect, &QPushButton::clicked, this, [this]{bool ret = Connect();qDebug() << "Connect:" << ret;if (ret){ui.label->setText("Connected");ui.label->setStyleSheet("background-color: rgb(0, 255, 0);");}else{ui.label->setText("Disconnected");ui.label->setStyleSheet("background-color: rgb(255, 0, 0);");}});connect(ui.pushButton_disconnect, &QPushButton::clicked, this, [this]{bool ret = Disconnect();qDebug() << "Disconnect:" << ret;if (ret){ui.label->setText("Connected");ui.label->setStyleSheet("background-color: rgb(0, 255, 0);");}else{ui.label->setText("Disconnected");ui.label->setStyleSheet("background-color: rgb(255, 0, 0);");}});connect(ui.pushButton_bit_write, &QPushButton::clicked, this, [this] {//对DB1 index0 bit0 这个位的值int i = ui.spinBox_bit_write->value();bool value = false;(i == 1)? value = true : value = false;bool ret = SetValue(1, 0, 0, value);if (!ret) {qDebug() << "SetValue_bool failed";return;}qDebug() << "SetValue_bool success";});connect(ui.pushButton_bit_read, &QPushButton::clicked, this, [this]{//读取DB1 index0 bit0 这个位的值bool value;bool ret = GetValue(1, 0, 0, value);if (!ret){qDebug() << "GetValue_bool failed";return;}qDebug() << "GetValue_bool success";ui.spinBox_bit_read->setValue(value ? 1 : 0);});connect(ui.pushButton_real_write, &QPushButton::clicked, this, [this] {float f_value = ui.doubleSpinBox_real_write->value();bool ret = SetValue(1, 0, 0, f_value);if (!ret){qDebug() << "SetValue_float failed";return;}qDebug() << "SetValue_float success";});connect(ui.pushButton_real_read, &QPushButton::clicked, this, [this]{//读取DB1 index0 real3 的值float f_value;bool ret = GetValue(1, 0, 0, f_value);if (!ret){qDebug() << "GetValue_float failed";return;}qDebug() << "GetValue_float success";ui.doubleSpinBox_real_read->setValue(f_value);});connect(ui.pushButton_string_write, &QPushButton::clicked, this, [this] {//int max_length = ui.lineEdit_string_write->text().length();//QString s_value = ui.lineEdit_string_write->text();int  max_length = 15;QString s_value = ui.lineEdit_string_write->text();bool ret = SetValue(1, 0, 0, max_length, s_value);if (!ret){qDebug() << "SetValue_string failed";return;}qDebug() << "SetValue_string success";});connect(ui.pushButton_string_read, &QPushButton::clicked, this, [this] {int max_length = 15;QString s_value;bool ret = GetValue(1, 0, 0, max_length, s_value);if (!ret){qDebug() << "GetValue_string failed";return;}qDebug() << "GetValue_string success";ui.lineEdit_string_read->setText(s_value);});}PLC_Demo_Qt::~PLC_Demo_Qt() {}bool PLC_Demo_Qt::Connect() {QMutexLocker locker(&mutex_);const int ret = client_->ConnectTo("127.0.0.1", 0, 0);if (ret != 0) {qCritical() << QString("Snap7Interface::Connect failed, code: 0x%1").arg(ret, 8, 16, QLatin1Char('0')).toUtf8().data();return false;}return true;
}bool PLC_Demo_Qt::IsConnected() {QMutexLocker locker(&mutex_);return client_->Connected();
}bool PLC_Demo_Qt::Disconnect() {QMutexLocker locker(&mutex_);return client_->Disconnect();
}void PLC_Demo_Qt::SetBit(unsigned char& byte, const int bit_index, const bool value)
{if (value) { byte |= 1 << bit_index; }else { byte &= ~(1 << bit_index); }
}
bool PLC_Demo_Qt::GetBit(const unsigned char& byte, const int bit_index) { return (byte & 1 << bit_index) != 0; }
bool PLC_Demo_Qt::isLittleEndian()
{uint16_t num = 1;return (*(reinterpret_cast<uint8_t*>(&num)) == 1);
}bool PLC_Demo_Qt::SetValue(const int db, const int index, const int bit, const bool value) {QMutexLocker locker(&mutex_);unsigned char buffer;int ret = client_->DBRead(db, index, 1, &buffer);if (ret != 0) {qCritical() << QString("Snap7Interface::SetValue read failed, code: 0x%1").arg(ret, 8, 16, QLatin1Char('0')).toUtf8().data();return false;}SetBit(buffer, bit, value);ret = client_->DBWrite(db, index, 1, &buffer);if (ret != 0) {qCritical() << QString("Snap7Interface::SetValue write failed, code: 0x%1").arg(ret, 8, 16, QLatin1Char('0')).toUtf8().data();return false;}bool is_set;if (!GetValue(db, index, bit, is_set)) {return false;}return is_set == value;
}bool PLC_Demo_Qt::GetValue(const int db, const int index, const int bit, bool& is_set)
{QMutexLocker locker(&mutex_);unsigned char buffer;const int ret = client_->DBRead(db, index, 1, &buffer);if (ret != 0){qCritical() << QString("Snap7Interface::GetValue_bool failed, code: 0x%1").arg(ret, 8, 16, QLatin1Char('0')).toUtf8().data();return false;}is_set = GetBit(buffer, bit);return true;
}bool PLC_Demo_Qt::SetValue(const int db, const int index, const int bit, const float f_value)
{QMutexLocker locker(&mutex_);uint8_t buffer[4];std::memcpy(buffer, &f_value, 4);// 检查字节序并进行转换if (isLittleEndian()){std::reverse(buffer, buffer + 4);}const int ret = client_->DBWrite(db, index, 4, buffer);if (ret != 0){qCritical() << QString("Snap7Interface::SetValue_int write failed, code: 0x%1").arg(ret, 8, 16, QLatin1Char('0')).toUtf8().data();return false;}return true;
}bool PLC_Demo_Qt::GetValue(const int db, const int index, const int bit, float& f_value)
{QMutexLocker locker(&mutex_);uint8_t buffer[4];const int ret = client_->DBRead(db, index, 4, buffer);if (ret != 0){qCritical() << QString("Snap7Interface::GetValue_float failed, code: 0x%1").arg(ret, 8, 16, QLatin1Char('0')).toUtf8().data();return false;}if (isLittleEndian()){std::reverse(buffer, buffer + 4);}std::memcpy(&f_value, buffer, 4);return true;
}bool PLC_Demo_Qt::SetValue(const int db, const int index, const int bit, const int max_length, const QString s_value)
{QByteArray byteArray = s_value.toUtf8();int actualLength = qMin(byteArray.size(), max_length);char* buffer = new char[max_length + 2];buffer[0] = static_cast<char>(max_length);buffer[1] = static_cast<char>(actualLength);std::memcpy(buffer + 2, byteArray.constData(), actualLength);int sizeToWrite = 2 + actualLength;int ret = client_->DBWrite(db, index, sizeToWrite, buffer);if (ret != 0){qCritical() << QString("Snap7Interface::SetValue_string write failed, code: 0x%1").arg(ret, 8, 16, QLatin1Char('0')).toUtf8().data();delete[] buffer;return false;}delete[] buffer;return true;
}bool PLC_Demo_Qt::GetValue(const int db, const int index, const int bit, const int max_length, QString& s_value)
{char* buffer = new(std::nothrow) char[max_length + 2];if (!buffer){std::cerr << "Memory allocation failed." << std::endl;return false;}int ret = client_->DBRead(db, index, max_length + 2, buffer);if (ret == 0){const int maxLength = static_cast<int>(buffer[0]);const int actualLength = static_cast<int>(buffer[1]);const QByteArray byteArray(buffer + 2, actualLength);s_value = QString::fromUtf8(byteArray);// 释放动态分配的内存delete[] buffer;return true;}else{std::cerr << "Failed to read string from DB1 78.0." << std::endl;// 释放动态分配的内存delete[] buffer;return false;}
}

④snap7.h

我们下载PLC的SDK里面的头文件,内容太多这里就不放了
snap7.h具体位置

继续

⑤snap7.cpp

我们下载PLC的SDK里面的对应头文件的实现,内容太多这里就不放了
snap7.cpp具体位置

继续

7,效果展示

Ⅰ. 打开serverdemo.exe

在这里插入图片描述

Ⅱ. 模拟PLC的IP选择本地就行

在这里插入图片描述

Ⅲ. 运行项目

①连接

在这里插入图片描述

②按bit读写

按bit读写,代码里面是DB1 Index0 bit0,也可以做个配置文件
在这里插入图片描述
在这里插入图片描述

③按real读写(其实就是float)

在这里插入图片描述
在这里插入图片描述

④按字符串读写(代码里面设置的字符串长度是15)

在这里插入图片描述
在这里插入图片描述

相关文章:

Qt项目实现对西门子PLC的读写操作(snap7)——C++

实际项目中需要用到对西门子PLC进行通讯&#xff0c;故进行记录&#xff0c;方便后续回顾复习 实现功能&#xff1a; ①PLC连接与断开 ②往PLC指定位置读写操作&#xff08;bit、real、string&#xff09; PLC中的real相当于C中的float&#xff0c;4字节&#xff0c;32bit 1&…...

Python字典深度解析:高效键值对数据管理指南

一、字典核心概念解析 1. 字典定义与特征 字典&#xff08;Dictionary&#xff09;是Python中​​基于哈希表实现​​的无序可变容器&#xff0c;通过键值对存储数据&#xff0c;具有以下核心特性&#xff1a; ​​键值对结构​​&#xff1a;{key: value}形式存储数据​​快…...

Java虚拟机面试题:垃圾收集(下)

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…...

9 C 语言变量详解:声明与定于、初始化与赋值、printf 输出与 scanf 输入、关键字、标识符命名规范

1 初识变量 1.1 变量的意义 在程序设计中&#xff0c;变量是程序中不可或缺的组成单位&#xff0c;最基本的存储单元。它如同现实生活中的容器&#xff0c;用于临时或长期保存各种类型的数据&#xff0c;为程序提供灵活的数据操作能力。 以选购手机为例&#xff0c;手机的各项…...

释放 Mac 存储空间:Ollama 模型迁移到外接 NVMe 磁盘

目录 背景一、准备工作1. 确认外接 NVMe 已挂载2. 创建模型目录 二、迁移已有模型数据&#xff08;可选&#xff09;三、配置模型目录1. 设置环境变量2. 使用软链接&#xff08;强烈推荐&#xff09; 四、测试是否成功 背景 在本地运行 Ollama 时&#xff0c;模型数据默认保存…...

spring-batch批处理框架(1)

学习链接 SpringBatch高效批处理框架详解及实战演练 spring-batch批处理框架(1) spring-batch批处理框架(2) spring batch官方文档 spring batch官方示例代码 - github 文章目录 学习链接一、课程目标课程目标课程内容前置知识适合人群 二、Spring Batch简介2.1 何为批处理…...

MCP系列:权限管理与隐私保护

前言 随着模型上下文协议(MCP)的广泛应用,安全性问题也逐步突显。在前几篇文章中,我们已经探讨了MCP的基本概念、技术架构、实践应用以及工具调用机制。本篇文章将聚焦于MCP的安全性考量,包括权限管理、隐私保护以及风险缓解策略。 对于企业和开发者而言,了解如何保障M…...

【25软考网工笔记】第二章(7)多路复用技术

目录 一、多路复用技术 1. 频分复用FDM 1&#xff09;频分复用的基本概念 2&#xff09;频分复用与相关技术 3&#xff09;注意事项与扩展 2. 时分复用 1&#xff09;同步时分复用 2&#xff09;统计时分复用 3&#xff09;同步时分复用与统计时分复用的对比 4&#…...

任意文字+即梦3.0的海报设计Prompt

即梦3.0版本发布后&#xff0c;对文字的呈现能力得到了极大的提升&#xff0c;网上也出现了各种文章教大家怎么写提示词。 但是你有没有发现一个问题&#xff0c;好的提示词是需要艺术细胞的&#xff0c;只有那些浸淫设计领域的专家总结的提示词才算上乘。 就像是给你一个主题…...

自动化测试相关协议深度剖析及A2A、MCP协议自动化测试应用展望

一、不同协议底层逻辑关联分析 1. OPENAPI协议 OPENAPI 协议核心在于定义 API 的规范结构&#xff0c;它使用 YAML 或 JSON 格式来描述 API 的端点、请求参数、响应格式等信息。其底层逻辑是构建一个清晰、标准化的 API 描述文档&#xff0c;方便不同的客户端和服务端进行对接…...

零基础上手Python数据分析 (18):Matplotlib 基础绘图 - 让数据“开口说话”

写在前面 —— 告别枯燥数字,拥抱可视化力量,掌握 Matplotlib 绘图基础 欢迎来到 “高效数据分析实战指南:Python零基础入门” 专栏! 经过前面 Pandas 模块的学习和实战演练,我们已经掌握了使用 Python 和 Pandas 进行数据处理、清洗、整合、分析的核心技能。 我们能够从…...

[特殊字符] AI 大模型的 Prompt Engineering 原理:从基础到源码实践

&#x1f31f; 引言&#xff1a;Prompt Engineering - AI 大模型的"魔法咒语" 在 AI 大模型蓬勃发展的当下&#xff0c;它们展现出令人惊叹的语言处理能力&#xff0c;从文本生成到智能问答&#xff0c;从机器翻译到代码编写&#xff0c;几乎涵盖了自然语言处理的各…...

C++ 基于多设计模式下的同步异步⽇志系统-1准备工作

一.项目介绍 项⽬介绍 本项⽬主要实现⼀个⽇志系统&#xff0c; 其主要⽀持以下功能: • ⽀持多级别⽇志消息 • ⽀持同步⽇志和异步⽇志 • ⽀持可靠写⼊⽇志到控制台、⽂件以及滚动⽂件中 • ⽀持多线程程序并发写⽇志 • ⽀持扩展不同的⽇志落地⽬标地 二.日志系统的三种实现…...

c# MES生产进度看板,报警看板 热流道行业可用实时看生产进度

MES生产进度看板&#xff0c;报警看板 热流道行业可用实时看生产进度 背景 本软件是给宁波热流道行业客户开发的生产电子看板软件系统 功能 1.录入工艺流程图&#xff08;途程图&#xff09;由多个站别组成。可以手动设置每个工艺站点完成百分比。 2.可以看生成到哪个工…...

C语言学习之预处理指令

目录 预定义符号 #define的应用 #define定义常量 #define定义宏 带有副作用的宏参数 宏替换的规则 函数和宏定义的区别 #和## #运算符 ##运算符 命名约定 #undef ​编辑 命令行定义 条件编译 头文件包含 头文件被包含的方式 1.本地头文件包含 2.库文件包含 …...

腾讯wxg企业微信 后端开发一面

UDP安全吗&#xff0c;怎么修改让其安全&#xff1f; packet header QUIC FrameHeader TCP的三个窗口 滑动 发送 拥塞&#xff0c; 怎么用UDP使用类似的功能 怎么确认消息是否收到? TCP的拥塞控制是怎么样的 HTTPS的握手流程 MySQL为什么用B树 红黑树等结构也能在叶子节点实现…...

【Hot100】 73. 矩阵置零

目录 引言矩阵置零我的解题优化优化思路分步解决思路为什么必须按照这个顺序处理&#xff1f;完整示例演示总结 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;算法专栏&#x1f4a5; 标题&#xff1a;【Hot100】 73. 矩阵置零❣️ 寄语&#xff…...

c++_csp-j算法 (2)

目录 BFS搜索(广度优先搜索) 讲解 BFS搜索算法原理 BFS搜索算法实现 BFS搜索算法的应用 例题(1) P1032 [NOIP 2002 提高组] 字串变换 例题(2) P1443 马的遍历 BFS搜索(广度优先搜索) 讲解 BFS搜索算法原理 广度优先搜索(BFS)算法是一种图的搜索算法,用于遍历…...

学习笔记: Mach-O 文件

“结构决定性质,性质决定用途”。如果不了解结构,是很难真正理解的。 通过一个示例的可执行文件了解Mach-O文件的结构 Mach-O基本结构 Header: &#xff1a;文件类型、目标架构类型等Load Commands&#xff1a;描述文件在虚拟内存中的逻辑结构、布局Data: 在Load commands中…...

基于GRPO将QWEN训练为和deepseek一样的推理模型!

GRPO 群体相对策略优化&#xff08;GRPO&#xff09;算法最初由deepseek团队提出&#xff0c;是近端策略优化(PPO)的一个变体。 GRPO 是一种在线学习算法&#xff0c;它通过使用训练过程中已训练模型自身生成的数据进行迭代改进。GRPO 目标背后的逻辑是在确保模型与参考策略保…...

STM32 外部中断EXTI

目录 外部中断基础知识 STM32外部中断框架 STM32外部中断机制框架 复用功能 重映射 中断嵌套控制器NVIC 外部中断按键控制LED灯 外部中断基础知识 STM32外部中断框架 中断的概念&#xff1a;在主程序运行过程中&#xff0c;出现了特点的中断触发条件&#xff0c;使得…...

Codex CLI - 自然语言命令行界面

本文翻译整理自&#xff1a;https://github.com/microsoft/Codex-CLI 文章目录 一、关于 Codex CLI相关链接资源 二、安装系统要求安装步骤 三、基本使用1、基础操作2、多轮模式 四、命令参考五、提示工程与上下文文件自定义上下文 六、故障排查七、FAQ如何查询可用OpenAI引擎&…...

健身会员管理系统(ssh+jsp+mysql8.x)含运行文档

健身会员管理系统(sshjspmysql8.x) 对健身房的健身器材、会员、教练、办卡、会员健身情况进行管理&#xff0c;可根据会员号或器材进行搜索&#xff0c;查看会员健身情况或器材使用情况。...

数据结构——快排和归并排序(非递归)

快速排序和归并排序一般都是用递归来实现的&#xff0c;但是掌握非递归也是很重要的&#xff0c;说不定在面试的时候面试官突然问你快排或者归并非递归实现&#xff0c;递归有时候并不好&#xff0c;在数据量非常大的时候效率就不好&#xff0c;但是使用非递归结果就不一样了&a…...

Trae,字节跳动推出的 AI 编程助手插件

Trae 插件是 Trae 旗下全新一代的人工智能编程助手&#xff08;前身为 MarsCode 编程助手&#xff09;&#xff0c;以插件形式集成在本地开发环境中&#xff0c;具备极高的兼容性和灵活性&#xff0c;旨在提升开发效率和代码质量。它支持超过100种编程语言&#xff0c;兼容主流…...

Qt项目——Tcp网络调试助手服务端与客户端

目录 前言结果预览工程文件源代码一、开发流程二、Tcp协议三、Socket四、Tcp服务器的关键流程五、Tcp客户端的关键流程六、Tcp服务端核心代码七、客户端核心代码总结 前言 这期要运用到计算机网络的知识&#xff0c;要搞清楚Tcp协议&#xff0c;学习QTcpServer &#xff0c;学…...

2021-11-10 C++蜗牛爬井进3退1求天数

缘由C大一编程题目。-编程语言-CSDN问答 int n 0, t 0;cin >> n;while ((n - 3)>0)n, t;cout << t << endl;...

玛哈特整平机:工业制造中的关键设备

在现代工业制造中&#xff0c;平整度是衡量材料加工质量的核心指标之一。无论是金属板材、塑料片材还是复合材料&#xff0c;若存在弯曲、翘曲或波浪形缺陷&#xff0c;将直接影响后续加工效率和成品质量。整平机&#xff08;又称校平机、矫平机&#xff09;作为解决这一问题的…...

LINUX419 更换仓库(没换成)find命令

NAT模式下虚拟机需与网卡处在同一个网段中吗 和VM1同个网段 会不会影响 这个很重要 是2 改成点2 倒是Ping通了 为啥ping百度 ping到别的地方 4399 倒是ping通了 准备下载httpd包 下不下来 正在替换为新版本仓库 报错 failure: repodata/repomd.xml from local: [Er…...

C# 预定义类型全解析

在 C# 编程中&#xff0c;预定义类型是基础且重要的概念。下面我们来详细了解 C# 的预定义类型。 预定义类型概述 C# 提供了 16 种预定义类型&#xff0c;包含 13 种简单类型和 3 种非简单类型。所有预定义类型的名称都由全小写字母组成。 预定义简单类型 预定义简单类型表…...

【仓颉 + 鸿蒙 + AI Agent】CangjieMagic框架(16):ReactExecutor

CangjieMagic框架&#xff1a;使用华为仓颉编程语言编写&#xff0c;专门用于开发AI Agent&#xff0c;支持鸿蒙、Windows、macOS、Linux等系统。 这篇文章剖析一下 CangjieMagic 框架中的 ReactExecutor。 这个执行器名字中的"React"代表"Reasoning and Acti…...

13.第二阶段x64游戏实战-分析人物等级和升级经验

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;12.第二阶段x64游戏实战-远程调试 效果图&#xff1a; 如下图红框&#xff0c;…...

Linux疑难杂惑 | 云服务器重装系统后vscode无法远程连接的问题

报错原因&#xff1a;本地的known_hosts文件记录服务器信息与现服务器的信息冲突了&#xff0c;导致连接失败。 解决方法&#xff1a;找到本地的known_hosts文件&#xff0c;把里面的所有东西删除后保存就好了。 该文件的路径可以在报错中寻找&#xff1a;比如我的路径就是&a…...

使用EXCEL绘制平滑曲线

播主播主&#xff0c;你都多少天没更新了&#xff01;&#xff01;&#xff01;泥在干什么&#xff1f;你还做这个账号麻&#xff1f;&#xff01;&#xff01;&#xff01; 做的做的&#xff08;哭唧唧&#xff09;&#xff0c;就是最近有些忙&#xff0c;以及…… 前言&…...

你的电脑在开“外卖平台”?——作业管理全解析

你的电脑在开“外卖平台”&#xff1f;——作业管理全解析 操作系统系列文章导航&#xff08;点击跳转&#xff09; 程序员必看&#xff1a;揭开操作系统的神秘面纱 &#xff1a;从进程、内存到设备管理&#xff0c;全面解析操作系统的核心机制与日常应用。告别电脑卡顿&#x…...

平均池化(Average Pooling)

1. 定义与作用​​ ​​平均池化​​是一种下采样操作&#xff0c;通过对输入区域的数值取​​平均值​​来压缩数据空间维度。其核心作用包括&#xff1a; ​​降低计算量​​&#xff1a;减少特征图尺寸&#xff0c;提升模型效率。​​保留整体特征​​&#xff1a;平滑局部…...

JavaScript中的Event事件对象详解

一、事件对象&#xff08;Event&#xff09;概述 1. 事件对象的定义 event 对象是浏览器自动生成的对象&#xff0c;当用户与页面进行交互时&#xff08;如点击、键盘输入、鼠标移动等&#xff09;&#xff0c;事件触发时就会自动传递给事件处理函数。event 对象包含了与事件…...

OSPF综合实验(HCIP)

1&#xff0c;R5为ISP&#xff0c;其上只能配置Ip地址&#xff1b;R4作为企业边界路由器&#xff0c; 出口公网地址需要通过ppp协议获取&#xff0c;并进行chap认证 2&#xff0c;整个OSPF环境IP基于172.16.0.0/16划分&#xff1b; 3&#xff0c;所有设备均可访问R5的环回&…...

Unreal 从入门到精通之如何接入MQTT

文章目录 前言MQTT 核心特性MQTT 在 UE5 中的应用场景在 UE5 中集成 MQTTMqtt Client 的APIMqtt Client 使用示例最后前言 MQTT(Message Queuing Telemetry Transport)是一种专为物联网(IoT)和低带宽、高延迟网络环境设计的轻量级消息传输协议。它采用发布/订阅(Pub/Sub)…...

数据结构实验6.2:稀疏矩阵的基本运算

文章目录 一&#xff0c;实验目的二&#xff0c;问题描述三&#xff0c;基本要求四、算法分析&#xff08;一&#xff09;稀疏矩阵三元组表示法存储结构&#xff08;二&#xff09;插入算法&#xff08;三&#xff09;创建算法&#xff08;四&#xff09;输出算法&#xff08;五…...

BDO分厂积极开展“五个一”安全活动

BDO分厂为规范化学习“五个一”活动主题&#xff0c;按照“上下联动、分头准备 、差异管理、资源共享”的原则&#xff0c;全面激活班组安全活动管理新模式&#xff0c;正在积极开展班组安全活动&#xff0c;以单元班组形式对每个班组每周组织一次“五个一”安全活动。 丁二醇单…...

那就聊一聊mysql的锁

MySQL 的锁机制是数据库并发控制的核心&#xff0c;作为 Java 架构师需要深入理解其实现原理和适用场景。以下是 MySQL 锁机制的详细解析&#xff1a; 一、锁的分类维度 1. 按锁粒度划分 锁粒度特点适用场景​全局锁​锁定整个数据库&#xff08;FLUSH TABLES WITH READ LOC…...

Python番外——常用的包功能讲解和分类组合

目录 1. Web开发框架与工具 2. 数据处理与分析 3. 网络请求与爬虫 4. 异步编程 5. 数据库操作 6. 图像与多媒体处理 7. 语言模型与NLP 8. 安全与加密 9. 配置与工具 10. 其他工具库 11.典型组合场景 此章节主要是记录我所使用的包&#xff0c;以及模块。方便供自己方…...

【mongodb】数据库操作

目录 1. 查看所有数据库2. 切换到指定数据库&#xff08;若数据库不存在&#xff0c;则创建&#xff09;3. 查看当前使用的数据库4. 删除当前数据库5.默认数据库 1. 查看所有数据库 1.show dbs2.show databases 2. 切换到指定数据库&#xff08;若数据库不存在&#xff0c;则…...

四月下旬系列

CUHKSZ 校赛 期中考试 DAY -1。 省流&#xff1a;前 1h 切 6 题&#xff0c;后 3h 过 1 题&#xff0c;读错一个本来很【】的题&#xff0c;被大模拟构造创【】了。 本地除了 VSCode 没有 Extensions&#xff0c;别的和省选差不多。使用 DEVC。 前 6 题难度 < 绿&#x…...

计算机网络 3-4 数据链路层(局域网)

4.1 局域网LAN 特点 1.覆盖较小的地理范围 2.较低的时延和误码率 3.局域网内的各节点之间 4.支持单播、广播、多播 分类 关注三要素 &#xff08;出题点&#xff09; ①拓扑结构 ②传输介质 ③介质访问控制方式 硬件架构 4.2 以太网 4.2.1 层次划分 4.2.2 物理层标准…...

WebSocket介绍

在网页聊天项目中&#xff0c;为了实现消息的发送和及时接收&#xff0c;我们使用了WebSocket&#xff0c;接下来就简单介绍一下这个WebSocket。 了解消息的转发逻辑 当两个不同客户端在不同的局域网中互相发送消息时&#xff0c;假如这两个客户端分别是a和b&#xff0c;因为…...

rpcrt4!COMMON_AddressManager函数分析之和全局变量rpcrt4!AddressList的关系

第一部分&#xff1a; 1: kd> x rpcrt4!addresslist 77c839dc RPCRT4!AddressList 0x00000000 1: kd> g Breakpoint 2 hit RPCRT4!OSF_ADDRESS::CompleteListen: 001b:77c0c973 55 push ebp 1: kd> g Breakpoint 11 hit RPCRT4!COMMON_Addr…...

Java Web 之 Tomcat 100问

Tomcat 是什么&#xff1f; Tomcat 是一个开源的 Java Servlet 容器和 Web 容器。 Tomcat 的主要功能有哪些&#xff1f; 三大主要功能&#xff1a; 运行 Java Web 应用。处理 HTTP 请求。管理 Web 应用。 如何安装 Tomcat &#xff1f; 下载 Tomcat 安装包&#xff08;A…...

ESB —— 企业集成架构的基石:功能、架构与应用全解析

企业服务总线&#xff08;Enterprise Service Bus&#xff0c;ESB&#xff09;是一种重要的企业级集成架构&#xff0c;以下为你详细介绍&#xff1a; 一、概念与定义 ESB 是一种基于面向服务架构&#xff08;SOA&#xff09;的中间件技术&#xff0c;它充当了企业内部不同应…...