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

【QT】基于UDP/TCP/串口 的Ymodom通讯协议客户端

【QT】基于UDP/TCP/串口的Ymodom通讯协议客户端

  • 前言
  • Ymodom实现
  • QT实现
    • 开源库的二次开发-1
    • 开源库的二次开发-2
  • 串口方式实现
  • TCP方式实现
  • UDP方式实现
  • 补充:文件读取
  • 补充:QT 封装成EXE

前言

Qt 运行环境 Desktop_Qt_5_11_2_MSVC2015_64bit ,基于Ymodom通讯协议,开发客户端实现与设备的UDP /TCP /串口通讯。在前期测试过程中,主要用了网络调试助手、串口调试助手、Virtual Serial Port Driver虚拟串口

对Ymodom的了解过程中,主要学习了博文Ymodem协议详解 、【嵌入式——QT】QT集成Ymodem协议使用UDP进行传输、qt随手记——ymodem协议使用,里面对协议的规则进行了详细的讲述,方便理解Ymodom 是什么。

在没有设备的情况下,用虚拟设备进行测试,发一个文件对应的指令如下:

43     ( C)
--
06   ( Ack)
43     ( C)
......
06   ( Ack)
----
04    (收 Eot)
15NAK04    (收 Eot)
06   ( Ack)
43     ( C)
--
06   ( Ack)

Ymodom实现

该协议包括起始帧、数据帧、结束帧,状态变量流转的方向如下:

YmodemFileTransmit.h
status : StatusEstablish->StatusTransmit ->StatusFinishymodem.h
stage:  StageNone-> StageEstablishing -> StageEstablished -> StageTransmitting->StageFinishing->StageFinished ->StageNone
code:  CodeNone

里面数据帧要注意,传1024或128规则如下:

  • 数据大于128,则按1024传;
  • 数据小于128,则按128传。

关于数据填充,看网上说是,以0x1A填充,但实际测试发现,是按照00填充的。

整个指令流程如下:
在这里插入图片描述

  • 接收方先发 43(C)
  • 发送方发 文件名+文件大小
  • 接收方发 06(Ack)
  • 接收方发 43(C)
  • 发送方开始一包包数据的发送,每发一包得等接收方回复 06(Ack)后再开始下一包
  • 当发完最后一包数据后,发送方发 04 (Eot)
  • 接收方发 15( NAK)
  • 发送方再发 04 (Eot)
  • 接收方发 06 ( Ack)
  • 接收方发 43(C),开始下一个文件传输
  • 如果不在发文件,则发送方发一包00数据
  • 接收方发 06(Ack),结束传输。

在传输中,使用的指令主要如下:

        CodeNone = 0x00,CodeSoh  = 0x01, //128字节数据包;CodeStx  = 0x02, //1024字节数据包;CodeEot  = 0x04, //文件传输结束指令;CodeAck  = 0x06, //接收正确指令;CodeNak  = 0x15, //重传当前数据包请求指令;CodeCan  = 0x18, //取消传输指令,连续发送5个该命令,终止传输;CodeC    = 0x43, //请求数据包CodeA1   = 0x41,CodeA2   = 0x61

QT实现

主要用得是Ymodem的开源库函数,然后对其进行二次开发。

开源库的二次开发-1

里面最主要的一个变更是,在传输完成进行二次回复确定时,接收方会发一个Ack过来,此时会调用transmitStageFinishing(),不难发现里面并没有关于Ack 的处理,此时会调用default: 处理:

如果一直没有发C指令,会不断累加定时器调用次数,由于设置一次定时器10ms,间隔5s后会重发04 (Eot)指令;如果超过设置的最大响应时间25s,会写取消传输指令。当然正常是不会有问题的,但是在测试时候,由于输入需要时间,时而会出现重发的情况,而且要注意这里的5s,是从第二次发完 EOT 后开始计算的。因此,对transmitStageFinishing() 增加Ack 处理 :

case CodeAck://sht-240813 add :避免发完ACK后C回复不及时,导致多发EOT指令{timeCount  = 0;errorCount = 0;dataCount  = 0;break;}

开源库的二次开发-2

第二个最大变更是,关于读取回复指令的长度设置,在部分的设备中,会存在回复指令加 0D 0A 的情况,用于分隔指令,因为接收方回复指令中存在连续发2个指令的情况,如果有了0D 0A 的加入,可以直接 以 06 0D 0A 43 0D 0A 方式发指令,当然也可以不用 0D 0A ,单纯只是用 06 43 或者间隔一下时间分别发,都可以。

既然出现了加 0D 0A 情况,那就要对读取进行二次处理,在receivePacket() 中将read(&(rxBuffer[0]), 1)修改为read(&(rxBuffer[0]), 3)

串口方式实现

最主要的就是串口收发一定要写好,Ymodom 部分主要就是进行虚函数复写就行。

QT += serialport
#include <QSerialPort>
QSerialPort * serialPort;
    if (serialPort->open(QSerialPort::ReadWrite) == true){//成功打开串口return true;}else{//串口打开失败return false;}
//读写指定长度len,存入buff
uint32_t YmodemFileTransmitSerial::read(uint8_t* buff, uint32_t len)
{return serialPort->read((char*)buff, len);
}uint32_t YmodemFileTransmitSerial::write(uint8_t* buff, uint32_t len)
{return serialPort->write((char*)buff, len);
}

TCP方式实现

QT       +=network
#include <QTcpSocket>
QTcpSocket * tcpClient;

这里一定要注意,平常会有信号触发的方式进行连接成功的判断,但为了减少跳转,以及代码逻辑的统一,这边采用了waitForConnected去进行连接成功与否的判断,设置的30000为等待连接时间,超过了则返回false。

tcpClient->connectToHost(targetAddr,serverPort);if(tcpClient->waitForConnected(30000)){//连接成功return true;}else{return false;}

这里也一定要注意,平常进行数据接收我们一般也是采用信号触发的方式,但这边不是,用得readwrite,传参分别是存储信息的地址和读取长度,返回实际读取长度。当发来一共10个字节,然后读了3个,后面7个字节会缓存,可以下次读,因此针对开源库的二次开发-2主要就是影响这里,加了0D 0A,在读1字节,就会有问题。

//-----------虚函数实现,读取内容----
uint32_t YmodemFileTransmitTcp::read(uint8_t *buff, uint32_t len)
{QByteArray array = tcpClient->read(len);uint32_t lenArray = array.size();uint32_t lenBuff  = len;uint32_t length = qMin(lenArray, lenBuff);memcpy(buff, array, length);return length;
}
//-----------虚函数实现,写内容----
uint32_t YmodemFileTransmitTcp::write(uint8_t *buff, uint32_t len)
{int ret = tcpClient->write((char*)buff, len);return ret;
}

UDP方式实现

QT       +=network
#include <QUdpSocket>
QUdpSocket* udpClient;

UDP也是一样的情况,由于不连接通讯,倒是不用增加连接步骤,但是接收信息不用常用的信号触发实现,也是直接用readwrite,其目的其实都是为了方便代码编写,更好使用Ymodom 库,确保三种方式逻辑编写规则统一。

//-----------虚函数实现,读取内容----
uint32_t YmodemFileTransmit::read(uint8_t* buff, uint32_t len)
{QNetworkDatagram datagram =udpClient->receiveDatagram(len);QByteArray array = datagram.data();uint32_t lenArray = array.size();uint32_t lenBuff  = len;uint32_t length = qMin(lenArray, lenBuff);memcpy(buff, array, length);return length;
}
//-----------虚函数实现,写内容----
uint32_t YmodemFileTransmit::write(uint8_t* buff, uint32_t len)
{QHostAddress targetAddr(serverIp);int ret = udpClient->writeDatagram((char*)buff, len, targetAddr, serverPort);return ret;
}

补充:文件读取

在开发中,需要涉及到文件的读取,为了方便后续的复用,这边也做一个整理

  • 找文件,存文件路径
#include <QFileDialog>
#include <QMessageBox>void BootLoader::on_pushButtonBrowse_clicked()
{QString curPath = QDir::currentPath();ui->lineEditFilePath->setText(QFileDialog::getOpenFileName(this, u8"打开文件", curPath, u8"任意文件 (*.*)"));
}
  • 读文件
#include <QFile>
QFile*       file;
YmodemFileTransmit::YmodemFileTransmit(QObject* parent) :QObject(parent),file(new QFile)
{
}
//-------------设置读取文件名--------
void YmodemFileTransmit::setFileName(const QString& name)
{file->setFileName(name);
}
//获取文件名 +文件大小
if(file->open(QFile::ReadOnly) == true) {QFileInfo fileInfo(*file);fileSize  = fileInfo.size();fileCount = 0;//将文件名fileInfo.fileName().toLocal8Bit().data()存buffstrcpy((char*)buff, fileInfo.fileName().toLocal8Bit().data());//将文件大小QByteArray::number(fileInfo.size()).data())存buffstrcpy((char*)buff + fileInfo.fileName().toLocal8Bit().size() + 1, QByteArray::number(fileInfo.size()).data());} 
//读YMODEM_PACKET_1K_SIZE最大长度的内容存buff,返回读取的实际长度。
//而且只要没有file->close();,file->read 会移动文件游标,读完一次后面接着读fileCount += file->read((char*)buff, YMODEM_PACKET_1K_SIZE);

补充:QT 封装成EXE

可以查看大神的博文【QT中如何生成导出.exe可执行文件并打包给其他人使用】,里面讲得很清晰。

相关文章:

【QT】基于UDP/TCP/串口 的Ymodom通讯协议客户端

【QT】基于UDP/TCP/串口的Ymodom通讯协议客户端 前言Ymodom实现QT实现开源库的二次开发-1开源库的二次开发-2 串口方式实现TCP方式实现UDP方式实现补充&#xff1a;文件读取补充&#xff1a;QT 封装成EXE 前言 Qt 运行环境 Desktop_Qt_5_11_2_MSVC2015_64bit &#xff0c;基于…...

超详细!!!electron-vite-vue开发桌面应用之引入UI组件库element-plus(四)

云风网 云风笔记 云风知识库 一、安装element-plus以及图标库依赖 npm install element-plus --save npm install element-plus/icons-vue npm i -D unplugin-icons二、vite按需引入插件 npm install -D unplugin-vue-components unplugin-auto-importunplugin-vue-componen…...

【排序篇】实现快速排序的三种方法

&#x1f308;个人主页&#xff1a;Yui_ &#x1f308;Linux专栏&#xff1a;Linux &#x1f308;C语言笔记专栏&#xff1a;C语言笔记 &#x1f308;数据结构专栏&#xff1a;数据结构 文章目录 1 交换排序1.1 冒泡排序1.2 快速排序1.2.1 hoare版本1.2.2 挖坑法1.2.3 前后指针…...

Java 标识符(详解)

文章目录 一、简介二、命名规则三、命名规范 一、简介 在 Java 中&#xff0c;用于给变量、类、方法等命名的符号组合&#xff0c;我们称之为Java标识符&#xff0c;它就像是给这些编程元素贴上的独特标签&#xff0c;以便在程序中能够准确地引用和操作它们。 二、命名规则 标…...

2024年,有哪些优质的计算机书籍推荐?

在2024年&#xff0c;计算机领域的新书层出不穷&#xff0c;涵盖了从基础理论到前沿技术的多个方面。以下是今年出版的几本备受关注的计算机新书。 1. AI与机器学习类 1、深度学习详解 1.李宏毅老师亲笔推荐&#xff0c;杨小康、周明、叶杰平、邱锡鹏鼎力推荐! 2.数百万次播…...

Python基础知识点--总结

1. 注释 注释用于提高代码的可读性&#xff0c;在代码中添加说明文字&#xff0c;使代码更容易理解。 单行注释&#xff1a;使用 # 符号开头&#xff0c;注释内容在符号之后的行内。多行注释&#xff1a;使用三引号&#xff08; 或 """&#xff09;包裹注释内…...

高效记录与笔记整理的策略:工具选择、结构设计与复习方法

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…...

Request重复读的问题

换了新工作都有时间写文章&#xff0c;每天也是加班到很晚&#xff0c;也不是工作内容多&#xff0c;主要是还是效率低&#xff0c;要考虑多干的很心累。 一、关于request重复读的问题&#xff0c;从源码的角度来分析 为什么他不能重复读 跳转 再看源码前可能需要一些基础的…...

Linux学习第60天:Linux驱动开发的一些总结

今天是Linux驱动开发的最后一个章节&#xff0c;题目中标明是60天完成的&#xff0c;其实在实际学习及笔记的整理中不止是60天。中间有过断更&#xff0c;有时断更的时间还是挺长的。这是在整个Linux驱动开发学习中最不满意的地方。 题目为Linux学习&#xff0c;其实这个题目有…...

OPP || 继承和抽象类 || 访问控制

OPP面向对象程序设计 数据抽象&#xff1a;类的接口声明和定义实现分离继承&#xff1a;类构成的&#xff08;树型&#xff09;层次关系动态绑定&#xff1a;忽略相似类型区别&#xff0c;用统一的方式使用 基类派生类&#xff1a; 继承&#xff1a;类名 冒号 访问说明符 …...

蓝牙音视频远程控制协议(AVRCP) command跟response介绍

零.声明 本专栏文章我们会以连载的方式持续更新&#xff0c;本专栏计划更新内容如下&#xff1a; 第一篇:蓝牙综合介绍 &#xff0c;主要介绍蓝牙的一些概念&#xff0c;产生背景&#xff0c;发展轨迹&#xff0c;市面蓝牙介绍&#xff0c;以及蓝牙开发板介绍。 第二篇:Trans…...

MySQL的InnoDB存储引擎中的Buffer Pool机制

目录 Buffer Pool 简介 定义 为什么需要Buffer Pool 图解重点知识 Buffer Pool 的组成 数据页&#xff08;Data Pages&#xff09; 索引页&#xff08;Index Pages&#xff09; 插入缓冲页&#xff08;Insert Buffer Pages&#xff09; undo页&#xff08;Undo Pages&a…...

5. MongoDB 文档插入、更新、删除、查询

1. 插入文档 文档的数据结构和JSON基本一样。所有存储在集合中的数据都是BSON格式。 BSON是一种类似JSON的二进制形式的存储格式&#xff0c;是Binary JSON的简称。常用的插入文档方法包括&#xff1a; db.collection.insertOne()&#xff1a;插入单个文档db.collection.inse…...

⌈ 传知代码 ⌋ DETR[端到端目标检测]

&#x1f49b;前情提要&#x1f49b; 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间&#xff0c;对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…...

Oracle之触发器

简介 触发器在数据库里以独立的对象存储&#xff0c;他与存储过程不同的是&#xff0c;存储过程通过其他程序来启动运行或直接启动运行而触发器是由一个事件来启动运行&#xff0c;即触发器是当某个事件发生时自动式运行。并企&#xff0c;触发器不能接收参数。所以运行触发器…...

从零搭建微前端架构:解耦大型项目的终极方案

随着前端应用的复杂度不断提升,单体前端应用(Monolithic Frontend)的维护和扩展难度也日益增加。微前端(Micro-Frontend)作为一种新兴架构理念,旨在将大型前端项目拆分为多个独立、可独立部署的微应用,从而提升项目的可维护性和灵活性。这篇文章将带你从零开始搭建一个微…...

24/8/17算法笔记 MPC算法

MPC算法&#xff0c;在行动前推演一下 MPC&#xff08;Model Predictive Control&#xff0c;模型预测控制&#xff09;是一种先进的控制策略&#xff0c;它利用未来预测模型来优化当前的控制动作。MPC的核心思想是&#xff0c;在每一个控制步骤中&#xff0c;都基于当前系统状…...

GROUP_CONCAT 用法详解(Mysql)

GROUP_CONCAT GROUP_CONCAT 是 MySQL 中的一个聚合函数&#xff0c;用于将分组后的多行数据连接成一个单一的字符串。 通常用于将某个列的多个值合并到一个字符串中&#xff0c;以便更方便地显示或处理数据。 GROUP_CONCAT([DISTINCT] column_name[ORDER BY column_name [ASC…...

Golang httputil 包深度解析:HTTP请求与响应的操控艺术

标题&#xff1a;Golang httputil 包深度解析&#xff1a;HTTP请求与响应的操控艺术 引言 在Go语言的丰富标准库中&#xff0c;net/http/httputil包是一个强大的工具集&#xff0c;它提供了操作HTTP请求和响应的高级功能。从创建自定义的HTTP代理到调试HTTP流量&#xff0c;h…...

SQLALchemy 分页

SQLALchemy 分页 1. 使用SQLAlchemy的`slice`和`offset`/`limit`SQLAlchemy 1.4及更新版本SQLAlchemy 1.3及更早版本使用第三方库注意事项在Web开发中,分页是处理大量数据时一个非常重要的功能。SQLAlchemy是一个流行的Python SQL工具包和对象关系映射(ORM)库,它允许开发者…...

快速上手体验MyPerf4J监控springboot应用(docker版快速开始-本地版)

使用MyPerf4J监控springboot应用 快速启动influxdb时序数据库日志收集器telegrafgrafana可视化界面安装最终效果 项目地址 项目简介: 一个针对高并发、低延迟应用设计的高性能 Java 性能监控和统计工具。 价值 快速定位性能瓶颈快速定位故障原因 快速启动 监控本地应用 idea配…...

C语言 之 strlen、strcpy、strcat、strcmp字符串函数的使用和模拟实现

文章目录 strlen的使用和模拟实现函数的原型strlen模拟实现&#xff1a;方法1方法2方法3 strcpy的使用和模拟实现函数的原型strcpy的模拟实现&#xff1a; strcat的使用和模拟实现函数的原型strcat的模拟实现&#xff1a; strcmp的使用和模拟实现函数的原型strcmp的模拟实现 本…...

CAPL使用结构体的方式组装一条DoIP车辆识别请求报文(payload type 0x0002)

DoIP车辆识别请求(payload type 0x0002)报文的格式为: /******************************************************** +--------+--------+--------+--------+ |version | inVer | type | +--------+--------+--------+--------+ | length …...

数据接入教学

数据接入教学 1、开通外部网络策略2、检查本地防火墙策略3、测试网络连通性4、工具抓包命令5、本地测试发送与监听 1、开通外部网络策略 保证外部网络联通、保证内部防火墙开通策略&#xff08;可以关闭进行测试&#xff09; 2、检查本地防火墙策略 关闭进行测试 停止firewa…...

炒作将引发人工智能寒冬

我们似乎经常看到人工智能的进步被吹捧为机器真正变得智能的一大飞跃。我将在这里挑选其中的一个例子&#xff0c;并确切解释为什么这种态度会为人工智能的未来埋下隐患。 这很酷&#xff0c;这是一个非常困难且非常具体的问题&#xff0c;这个团队花了3 年时间才解决。他们一定…...

clamp靶机复现

靶机设置 设置靶机为NAT模式 靶机IP发现 nmap 192.168.112.0/24 靶机IP为192.168.112.143 目录扫描 dirsearch 192.168.112.143 访问浏览器 提示让我们扫描更多的目录 换个更大的字典&#xff0c;扫出来一个 /nt4stopc/ 目录 目录拼接 拼接 /nt4stopc/ 发现页面中有很多…...

mfc100u.dll丢失问题分析,详细讲解mfc100u.dll丢失解决方法

面对mfc100u.dll文件丢失带来的挑战时&#xff0c;许多用户都可能感到有些无助&#xff0c;尤其是当这一问题影响到他们日常使用的软件时。但实际上&#xff0c;存在几种有效方法可以帮助您快速恢复该关键的系统文件。为了方便不同水平的用户&#xff0c;本文将详细解析各种处理…...

【C++】什么是内存管理?

如果有不懂的地方&#xff0c;可以看我以往文章哦&#xff01; 个人主页&#xff1a;CSDN_小八哥向前冲 所属专栏&#xff1a;C入门 目录 C/C内存分布 C内存管理方式 new/delete操作内置类型 new/delete操作自定义类型 operator new与operator delete函数 new和delete实现…...

产业经济大脑建设方案(五)

为了提升产业经济的智能化水平&#xff0c;我们提出建设一个综合产业经济大脑系统&#xff0c;该系统通过整合大数据分析、人工智能和云计算技术&#xff0c;构建全方位的数据采集、处理和决策支持平台。该平台能够实时监测产业链各环节的数据&#xff0c;运用智能算法进行深度…...

如何在 Odoo 16 中覆盖创建、写入和取消链接方法

Odoo 是一款强大的开源业务应用程序套件&#xff0c;可为各种业务运营提供广泛的功能。其主要功能之一是能够自定义和扩展其功能以满足特定的业务需求。在本博客中&#xff0c;我们将探讨如何覆盖Odoo 16中的创建、写入和取消链接方法&#xff0c;从而使您无需修改​​核心代码…...

pip离线安装accelerate

一、离线下载到当前文件夹 pip download accelerate -d ./anzhuangbao# 制定版本使用以下命令pip download accelerate0.32.0 -d ./anzhuangbao二、离线安装 cd anzhuangbaipip install --no-index --find-links. accelerate三、验证是否安装 pip show accelerateAccelerate: …...

VUE3请求意外报跨越错误或者500错误问题

1.有可能是请求传参和传参类型写错了 首先要确保该请求接口是支持跨域的&#xff08;不支持叫后端改&#xff09; access-control-allow-headers:Content-Type, Accept, Access-Control-Allow-Origin, api_key, Authorization access-control-allow-methods:GET, POST, OPTIO…...

vue 关于两个if条件中的promise

一、案例效果 期望if判断条件里的两个promise 都同时执行完成 二、 初始代码案例 const formatDetail async (fnArgsJsonParams: MapLogicType) > {if (fnArgsJsonParams?.targetFeatureName) {const resDetailData await formatFeatureInfo(fnArgsJsonParams.targetF…...

C/C++移位运算问题

目录 上期答案揭晓&#xff1a; 回忆&#xff1a; 问题1展现&#xff1a; 问题2展现&#xff1a; 改进方案&#xff1a; 下期预告&#xff1a;C语言类型转换的问题。 上期答案揭晓&#xff1a; 上期的问题大家是否都有了想法&#xff0c;下面说说我的思路。 上次我们提到…...

录屏工具 Icecream Screen Recorder PRO v7.41

Icecream Screen Recorder的免费屏幕录制工具&#xff0c;具备捕捉视频、音频、图片和游戏等多种功能。以前推荐过的icecreamPDF也是他家的非常好用&#xff01; 下载链接&#xff1a;「录屏」来自UC网盘分享https://drive.uc.cn/s/b474616b91534...

解决连接不上Linux和服务器中的Nacos(Windows中能连接但是Linux中却不行)

报错 com.alibaba.nacos.shaded.io.grpc.StatusRuntimeException: UNKNOWN: Uncaught exception in the SynchronizationContext. Re-thrown. at com.alibaba.nacos.shaded.io.grpc.Status.asRuntimeException(Status.jav 2024-08-13T10:21:52.93708:00 ERROR 27764 --- …...

【LLM大语言模型-开篇】LLM入门实践指南

"LLM入门实践指南"是一个通过代码实践&#xff0c;为大模型入门读者提供全面且较为深入的大模型技术视角的教程。 为何关注LLM&#xff1f; 创新与变革&#xff1a;LLM不仅推动了自然语言处理&#xff08;NLP&#xff09;领域的进步&#xff0c;还在诸多行业中催生了…...

实时视频换脸、8 万家 AI 公司消失、论文天价售卖、新的 scaling law、爆火毒舌 AI | AI 掘金视界周刊第 5 期

AI 视界周刊由战场小包维护&#xff0c;每周一更新&#xff0c;包含热点聚焦、应用破局、学术前沿、社区热议、智见交锋、跨界 AI、企业动态和争议 AI 八大板块&#xff0c;后续板块划分和内容撰写在周刊迭代过程中持续优化&#xff0c;欢迎大家提出建议。 欢迎大家来到《AI 视…...

XSS靶场(1-11关)

目录 简述xss xss第1关 xss第2关 ​编辑 xss第3关 xss第4关 xss第5关过滤了 on script xss第6关 xss第7关 xss第8关 xss第9关 xss第10关 xss11关 我把源代码靶场放到了最顶端 简述xss XSS攻击通常指的是通过利用网页开发时留下的漏洞&#xff0c;通过巧妙的方法…...

vue2 子组件props接收父组件对象或数组必须使用函数进行返回

export default{ name:MyComponent, props:{ title:{ type:String, default:"" }, age:{ type:Number, default:1 }, names:{ type:Array, //数组或对象必须用函数进行返回 default:function(){ return [] …...

【算法/学习】双指针

✨ 少年要迎着朝阳&#xff0c;活得肆无忌惮 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;算法学习 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &a…...

Springboot集成Liquibase笔记整理

添加依赖<dependency><groupId>org.liquibase</groupId><artifactId>liquibase-core</artifactId> </dependency>添加配置spring:liquibase:contexts: dev,testenabled: true编写liquibase配置类Configuration EnableConfigurationPropert…...

Python拆分无atlas图集(瑕疵版)

老板给了张没有atlas文件的图集让我拆图&#xff0c;简单写了一版凑合用。 存在的问题&#xff1a; 可能会拆出来一些小尺寸的透明像素图片&#xff1b;可能会拆出来一些偏大的小图的整体集合&#xff1b;可能会把应该是一块的小图批成两半&#xff0c;不过不多&#xff1b;其…...

SQLALchemy 排序

SQLALchemy 排序 基本用法多列排序使用函数或表达式进行排序注意事项在SQLAlchemy中,排序(Ordering)是通过order_by()方法实现的。这个方法允许你指定一个或多个列(或表达式),用于对查询结果进行排序。你可以指定升序(默认)或降序排序。 基本用法 假设你有一个User模…...

【iOS】Block底层分析

目录 前言Block底层结构Block捕获变量原理捕获局部变量&#xff08;auto、static&#xff09;全局变量捕获实例self Block类型Block的copyBlock作为返回值将Block赋值给__strong指针Block作为Cocoa API中方法名含有usingBlock的方法参数Block作为GCD API的方法参数Block属性的写…...

复现dom破坏案例和靶场

文章目录 靶场网址第一个实验步骤和原理(代码为示例要根据自己的实验修改) 第二个实验步骤和原理(代码为示例要根据自己的实验修改) 靶场网址 注册后点击 第一个实验 此实验室包含一个 DOM 破坏漏洞。注释功能允许“安全”HTML。为了解决这个实验&#xff0c;请构造一个 HT…...

【高校科研前沿】南方科技大学冯炼教授等人在遥感顶刊RSE发文:全球人类改造的基塘系统制图

1.文章简介 论文名称&#xff1a;Global mapping of human-transformed dike-pond systems&#xff08;全球人类改造的基塘系统制图&#xff09; 第一作者及单位&#xff1a;Yang Xu&#xff08;南方科技大学环境学院&#xff09; 第一通讯作者及单位&#xff1a;冯炼&#x…...

How to run angular CICD on gitlab-runner of wsl?

前提文件 .gitlab-ci.yml, .dockerignore, ci-funcs.sh, Dockerfile, karma.conf.js, nginx.conf, nginx-custom.conf, sonar-project.properties 1.test.ts const context require.context(./app/pages, true, /\.spec\.ts$/); 2.sonar-project.properties sonar.sourcessrc/…...

搭建Java集成开发环境IntelliJ IDEA

搭建Java集成开发环境&#xff08;Integrated Development Environment&#xff0c;简称IDE&#xff09;IntelliJ IDEA是一个涉及多个步骤的过程&#xff0c;旨在帮助Java开发者高效、舒适地进行编程工作。IntelliJ IDEA由JetBrains公司开发&#xff0c;以其强大的代码自动补全…...

JS逆向浏览器脱环境专题:事件学习和编写、DOM和BOM结构、指纹验证排查、代理自吐环境通杀环境检测、脱环境框架、脱环境插件解决

&#x1f310;JS逆向浏览器脱环境专题&#xff1a;事件学习和编写、DOM和BOM结构、指纹验证排查、代理自吐环境通杀环境检测、脱环境框架、脱环境插件解决 &#x1f5a5;️ 浏览器事件学习和编写 浏览器事件是用户与网页交互的主要方式&#xff0c;了解并掌握这些事件的处理方…...