QT——串口调试助手
目录
1.QSerialPort类包含了很多有关串口的API
2.实现串口的打开
2.1 方法一:通过函数实现
2.2 方法二:在ui界面右下角实现
3. 实现定时发送
3.1类的私有成员中添加定时器QTimer timer并去构造函数中初始化它
3.2帮助文档中有QTimer类相关的说明
3.3去连接该超时信号与槽函数
4.俩种方式实现时间显示
4.1通过线程实现
4.2 通过定时器实现时间显示
5. 实现发送与接收
6.实现Hex显示——实现每俩个字节加一个空格显示
7.文本框追加内容时注意事项
8.重写QComboBox组件的事件 —— 实现串口号的刷新
9.实现多文本发送
10.循环发送
第一种方法:不能通过延时函数处理,此方法为错误案例
第二种方法:定时器
第三种方法:多线程
11.Qt打包程序
1.首先切换为release,然后重新构建,并且运行
2.拷贝库文件
3.手动拷贝缺失库文件
4.整体进行压缩
1.QSerialPort类包含了很多有关串口的API
静态公有成员中提供了availablePorts()
函数去获取我当前电脑中存在的所有串口,存放在容器中元素类型是QSerialPortInfo
// 获取当前系统中存在的串口QList<QSerialPortInfo> serialList = QSerialPortInfo::availablePorts();// 使用 qDebug 输出串口信息for (QSerialPortInfo serialinfo : serialList) {qDebug() << "Port Name:" << serialinfo.portName() //端口名称<< ", Description:" << serialinfo.description() //描述<< ", Manufacturer:" << serialinfo.manufacturer() //制造商<< ", Serial Number:" << serialinfo.serialNumber(); //序列号ui->comboBox_01->addItem(serialinfo.portName()); //向combox组件中添加端口名称}
2.实现串口的打开
想要实现打开串口/关闭串口按键的点击反转,需要绑定槽函数中信号是clicked(bool checked),而不是普通的clicked()信号, 并且需要使得该按键状态是可以检测的,这里有俩种方法
2.1 方法一:通过函数实现
ui->btn_CloseOrOpenSerial->setCheckable(true);
2.2 方法二:在ui界面右下角实现
3. 实现定时发送
3.1类的私有成员中添加定时器QTimer timer并去构造函数中初始化它
3.2帮助文档中有QTimer类相关的说明
- 设置定时器间隔时间
void setInterval(int time);
- Signals中包含信号检测是否超时
void timeout();
3.3去连接该超时信号与槽函数
- 在超时信号的槽函数里面进行数据的发送
4.俩种方式实现时间显示
4.1通过线程实现
curtimeupdate.h
#ifndef CURTIMEUPDATE_H
#define CURTIMEUPDATE_H#include <QDateTime>
#include <QThread>
#include <QObject>class curTimeUpdate : public QThread {Q_OBJECTpublic:explicit curTimeUpdate(QObject *parent = nullptr): QThread(parent){};signals:void updateTime(const QString &timeString);protected:// 每间隔1s发送一次时间信号void run() override{while(1){// 获取当前时间QDateTime dataTime = QDateTime::currentDateTime();QDate date = dataTime.date();int year = date.year();int month = date.month();int day = date.day();QTime time = dataTime.time();int hour = time.hour();int minute = time.minute();int second = time.second();// 将时间拼装起来,确保月份和日期、小时、分钟、秒钟都是双位数QString currentTime = QString("%1-%2-%3 %4:%5:%6").arg(year).arg(month, 2, 10, QChar('0')) // 确保月是两位数.arg(day, 2, 10, QChar('0')) // 确保日是两位数.arg(hour, 2, 10, QChar('0')) // 确保小时是两位数.arg(minute, 2, 10, QChar('0')) // 确保分钟是两位数.arg(second, 2, 10, QChar('0')); // 确保秒钟是两位数//发送信号emit updateTime(currentTime);sleep(1);}}};#endif // CURTIMEUPDATE_H
widget.cpp
// 创建线程更新右下角时间timeUpdater = new curTimeUpdate;connect(timeUpdater, &curTimeUpdate::updateTime, this, &Widget::updateTimeLabel);timeUpdater->start(); // 启动线程
void Widget::updateTimeLabel(const QString &timeString) {ui->label_nowTime->setText(timeString); // 更新标签显示时间
}
4.2 通过定时器实现时间显示
实现逻辑:定时器定时1s,每当定时器超时,会自动发出超时信号,检测到该信号时,调用槽函数实现当前时间的获取
widget.h中添加以下内容
Private:QTimer* getSysTimeTimer;
private slots:void getSysTime();
widget.cpp
getSysTimeTimer = new QTimer(this);getSysTimeTimer->setInterval(1000); //设置定时器2的间隔时间(毫秒)connect(getSysTimeTimer, &QTimer::timeout, this, &Widget::getSysTime); //定时器2超时getSysTimeTimer->start(); //启动定时器2// 定时器超时槽函数
void Widget::getSysTime()
{// 获取当前时间QDateTime dataTime = QDateTime::currentDateTime();QDate date = dataTime.date();QTime time = dataTime.time();// 提取年、月、日、时、分、秒int year = date.year();int month = date.month();int day = date.day();int hour = time.hour();int minute = time.minute();int second = time.second();// 将时间拼装起来,确保月份和日期、小时、分钟、秒钟都是双位数QString currentTime = QString("%1-%2-%3 %4:%5:%6").arg(year).arg(month, 2, 10, QChar('0')) // 确保月是两位数.arg(day, 2, 10, QChar('0')) // 确保日是两位数.arg(hour, 2, 10, QChar('0')) // 确保小时是两位数.arg(minute, 2, 10, QChar('0')) // 确保分钟是两位数.arg(second, 2, 10, QChar('0')); // 确保秒钟是两位数// 更新标签显示时间ui->label_nowTime->setText(currentTime);
}
5. 实现发送与接收
// 发送按键槽函数
void Widget::on_pushButton_19_clicked()
{int WriteCnt = 0;QString sendData = ui->lineEdit_4->text();//Hex发送是否勾选,此处为勾选if(ui->checkBox_15->isChecked()){QByteArray tmpArray = ui->lineEdit_4->text().toLocal8Bit();//检查字节数是否是偶数if(tmpArray.size() % 2 != 0){ui->label_5->setText("input error!");return;}//检查是否符合16进制表达for(char c:tmpArray){if(!std::isxdigit(c)){ui->label_5->setText("input error!");return;}}//检查是否添加新行if(ui->checkBox_14->isChecked()){tmpArray = tmpArray.append("\\r\\n");}//转化为16进制发送QByteArray tmp = QByteArray::fromHex(tmpArray);WriteCnt = serialPort->write(tmp);}else{QByteArray data = sendData.toLocal8Bit();//检查是否添加新行if(ui->checkBox_14->isChecked()){data = data.append("\\r\\n");}WriteCnt = serialPort->write(data);}if(WriteCnt == -1){ui->label_5->setText("Send false!");}else{ui->label_5->setText("Send Ok!");ui->label_4->setText("Send: " + QString::number(WriteCntTotal));if(0 != strcmp(sendBak.toLocal8Bit().constData(), sendData.toLocal8Bit().constData())){ui->textEdit_Record->append(sendData);sendBak = sendData;}}}
// 接受数据槽函数
void Widget::on_SerialData_reched()
{QString revData = serialPort->readAll(); // 读取所有可用的数据qDebug() << "接受到的新数据为:" << revData;if(revData != NULL){//a.是否勾选自动换行if(ui->checkBox_6->isChecked()) revData.append("\\r\\n");//b.更新接受长度RevCntTotal += revData.size(); // 统计接受到的字节数ui->label_7->setText("Rev OK!");ui->label_3->setText("Rev: " + QString::number(RevCntTotal));//c.检查hex显示是否勾选if(ui->checkBox_5->isChecked()){//将新数据转化为HexQByteArray tmp = revData.toUtf8();qDebug() << "tmp:" <<tmp;QByteArray tmpHexString = revData.toUtf8().toHex().toUpper();qDebug() << "转化后的新数据为:" << tmpHexString;//获取旧数据QString tmpStringHex = ui->textEdit_Rev->toPlainText(); //因为勾选了,读出来的就是hex//拼接旧数据与新数据tmpHexString = tmpStringHex.toUtf8() + tmpHexString;//重新显示在控件上ui->textEdit_Rev->setText(tmpHexString);}else{//接受时间是否勾选,此处为未勾选if(ui->checkBox_4->checkState()== Qt::Unchecked){ui->textEdit_Rev->insertPlainText(revData);}else{getSysTime();ui->textEdit_Rev->insertPlainText("【"+currentTime+"】 "+revData);}}}
}
6.实现Hex显示——实现每俩个字节加一个空格显示
在 QString
类中,mid()
函数用于提取字符串的子字符串。
QString mid(int position, int length);
//position: 指定从哪个位置开始提取子字符串
//length: 指定要提取的字符数。如果这个参数省略,则默认提取到字符串的末尾。
// Hex显示槽函数
void Widget::on_checkBox_5_clicked(bool checked)
{if (checked) {// 获取原始文本 QString \\x01\\x02\\x03QString revDisplay = ui->textEdit_Rev->toPlainText();// 转换为 QByteArray \\x01\\x02\\x03QByteArray byteArray = revDisplay.toUtf8();// 转换为 QByteArray 010203byteArray = byteArray.toHex(); QString lastShow;// 转换为 QString 010203revDisplay = QString::fromUtf8(byteArray); for(int i=0; i<revDisplay.size();i+=2){lastShow += revDisplay.mid(i,2) + " ";}// 显示添加空格后的16进制内容ui->textEdit_Rev->setText(lastShow);} else {// 获取 Hex 文本QString hexDisplay = ui->textEdit_Rev->toPlainText();// 将 Hex 转换回原始字符串//QByteArray \\x01\\x02\\x03QByteArray byteArray = QByteArray::fromHex(hexDisplay.toUtf8());//QString \\x01\\x02\\x03QString normalDisplay = QString::fromUtf8(byteArray);// 设置文本为正常字符串ui->textEdit_Rev->setText(normalDisplay);}
}
7.文本框追加内容时注意事项
我们使用的函数是insertPlainText()
而不是append()
。因为append()
函数添加为内容后会自动换行。
8.重写QComboBox组件的事件 —— 实现串口号的刷新
- 当鼠标按下QComboBox组件时,发送
reflesh()
刷新信号。 - 在widget.cpp中连接该
reflesh()
信号与槽函数,槽函数中实现串口号的检测刷新。
mycombobox.h
#ifndef MYCOMBOBOX_H
#define MYCOMBOBOX_H#include <QComboBox>class myCombobox : public QComboBox
{Q_OBJECT
public:myCombobox(QWidget *parent);
protected:void mousePressEvent(QMouseEvent *e) override; //鼠标按下事件signals:void reflesh(); //刷新信号
};#endif // MYCOMBOBOX_H
mycombobox.cpp
#include "mycombobox.h"#include <QMouseEvent>myCombobox::myCombobox(QWidget *parent):QComboBox(parent)
{}void myCombobox::mousePressEvent(QMouseEvent *e)
{if(e->button() == Qt::LeftButton){emit reflesh();}QComboBox::mousePressEvent(e);
}
9.实现多文本发送
构造函数中先生成按键的名称,然后查找系统中是否有该名字的按键,有的话指针指向它,接着给该按键绑定槽函数
for(int i = 1; i <= 8; i++){QString btnName = QString("pushButton_%1").arg(i); //生成按键名字QPushButton* btn = findChild<QPushButton *>(btnName); //查找组件中是否有该名字的按键,若有,将指针指向该按键if(btn){btn->setProperty("buttonId",i); //给该按键添加属性buttons.append(btn); //将该按键添加到容器中connect(btn,SIGNAL(clicked()),this,SLOT(on_command_button_clicked()));//给该按键连接信号与槽函数}QString lineEditName = QString("lineEdit_%1").arg(i); //生成输入框名字QLineEdit *lineEdit = findChild<QLineEdit *>(lineEditName); //查找组件中是否有该名字的输入框,若有,将指针指向该输入框lineEdits.append(lineEdit); //将该输入框添加到容器中QString checkBoxName = QString("checkBox_%1").arg(i); //生成checkboBox名字QCheckBox *checkBox = findChild<QCheckBox *>(checkBoxName); //查找组件中是否有该名字的checkboBox,若有,将指针指向该checkboBoxcheckBoxs.append(checkBox); //将该checkboBox添加到容器中}
槽函数中先通过sender()函数获取到发送信号的对象,接着获取按键的属性,接着根据属性生成对应的名称
void Widget::on_command_button_clicked() {// 通过 sender() 函数获取发出信号的对象,在通过 qobject_cast<> 方法进行类型转换QPushButton *btn = qobject_cast<QPushButton *>(sender());if (btn) {// 获取按键的属性 buttonId 的值,并转换为整数int num = btn->property("buttonId").toInt();// 根据 buttonId 构造与之对应的 QLineEdit 对象的名称QString lineEditName = QString("lineEdit_%1").arg(num);QLineEdit *lineEdit = findChild<QLineEdit *>(lineEditName);if (lineEdit) {if (lineEdit->text().isEmpty()) {return; // 如果文本为空,直接返回,不发送}ui->lineEdit_sendData->setText(lineEdit->text());}// 根据 buttonId 构造与之对应的 QCheckBox 对象的名称QString hexName = QString("checkBox_%1").arg(num);QCheckBox *checkBox = findChild<QCheckBox *>(hexName);ui->checkBox_sendHex->setChecked(checkBox ? checkBox->isChecked() : false); // 确保 checkBox 存在后再获取状态// 只有在 lineEdit 有内容的情况下发送数据on_pushButton_send_clicked();}
}
10.循环发送
第一种方法:不能通过延时函数处理,此方法为错误案例
//循环发送()
void Widget::on_checkBox_cirSend_clicked(bool checked)
{if(checked){for(QPushButton *btn : buttons){//当前按键发送点金信号emit btn->clicked();QThread::msleep(ui->spinBox->text().toInt());}}
}
第二种方法:定时器
实现逻辑:当勾选循环发送时候,调用槽函数:去设置定时器的间隔时间,并且启动定时器。当定时器超时时候,执行槽函数去发送信号。
void Widget::on_checkBox_cirSend_clicked(bool checked)
{if(checked){timer3->setInterval(ui->spinBox->text().toInt());timer3->start(); // 启动定时器}else{timer3->stop();}
}void Widget::buttons_handler()
{if(btnIndex < 8){QPushButton *btn = buttons[btnIndex];emit btn->click();btnIndex++;}else{btnIndex = 0;}
}
第三种方法:多线程
缺点,没办法与ui组件关联,无法通过ui组件获取定时时间。
11.Qt打包程序
11.1.首先切换为release,然后重新构建,并且运行
11.2.拷贝库文件
首先进入C盘
C:
进入你程序的目录下
cd C:\\Users\\mi\\Desktop\\Qt Project\\build-untitled-Desktop_Qt_5_12_9_MinGW_64_bit-Release\\release
执行命令,拷贝库到该目录下
D:\\Linux\\Qt\\5.12.9\\mingw73_32\\bin\\windeployqt.exe untitled.exe
11.3.手动拷贝缺失库文件
11.4.整体进行压缩即可
12.整体代码如下
tunnek/QT- (github.com)
相关文章:

QT——串口调试助手
目录 1.QSerialPort类包含了很多有关串口的API 2.实现串口的打开 2.1 方法一:通过函数实现 2.2 方法二:在ui界面右下角实现 3. 实现定时发送 3.1类的私有成员中添加定时器QTimer timer并去构造函数中初始化它 3.2帮助文档中有QTimer类相关的说明 …...

国产操作系统卖疯了!最营收7.84亿,最低1.5亿
最近看各种报道,似乎国产化有提速的绩效,那么既然如此,各个国产操作系统厂商是不是都起飞了呢? 周末闲暇之余,我们来看看各家的营收表现。 银河麒麟2024年1-9月一共卖了多少钱? 前几天中国软件发布了202…...
2024年华为OD机试真题-最小的调整次数-Python-OD统一考试(E卷)
最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客 每一题都含有详细的解题思路和代码注释,精编c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,发现新题及时跟新。 题目描述: 有一个特异性的…...
React.js教程:从JSX到Redux的全面解析
文章目录 介绍react脚手架jsx语法和react组件jsx的基本语法jsx的行内样式jsx的类名classNameif条件渲染map循环渲染创建组件方法 可视区渲染 (React- virtualized)React-redux 介绍 javascript库,起源于Facebook的内部项目,类似于vue特点 声明式组件化 …...

二叉苹果树
AcWing 1074. 二叉苹果树【有依赖背包DP】 - AcWing 问题描述 在一棵有权无向树中,从某个节点(这里假设为节点 1)出发,遍历树的子节点,每经过一条边会获得对应的权重值。在访问节点数的限制下(即体积限制…...

【大数据学习 | kafka】producer的参数与结构
1. producer的结构 producer:生产者 它由三个部分组成 interceptor:拦截器,能拦截到数据,处理完毕以后发送给下游,它和过滤器不同并不是丢弃数据,而是将数据处理完毕再次发送出去,这个默认是不…...

2. 从服务器的主接口入手
Webserver 的主函数 main.cpp,完成了哪些功能? #include "config.h"int main(int argc, char *argv[]) {string user "";string passwd "";string databasename "";Config config;config.parse_arg(argc, a…...

nginx上传文件超过限制大小、响应超时、反向代理请求超时等问题解决
1、文件大小超过限制 相关配置: client_max_body_size: Syntax:client_max_body_size size;Default:client_max_body_size 1m;Context:http, server, location 2、连接超时: proxy_read_timeout: Syntax:proxy_read_timeout time;Default…...

第16课 核心函数(方法)
掌握常用的内置函数及其用法。 数学类函数:abs、divmod、max、min、pow、round、sum。 类型转换函数:bool、int、float、str、ord、chr、bin、hex、tuple、list、dict、set、enumerate、range、object。 序列操作函数:all、any、filter、m…...

【工具变量】中国制造2025试点城市数据集(2000-2023年)
数据简介:《中国制造2025》是中国ZF于2015年5月8日印发的一项战略规划,旨在加快制造业的转型升级,提升制造业的质量和效益,实现从制造大国向制造强国的转变。该规划是中国实施制造强国战略的第一个十年行动纲领,明确提…...

vscode makfile编译
MinGW-w64下载安装 为了在 Windows 上安装 GCC,您需要安装 MinGW-w64。 MinGW-w64 是一个开源项目,它为 Windows 系统提供了一个完整的 GCC 工具链,支持编译生成 32 位和 64 位的 Windows 应用程序。 访问 MinGW-w64 的主页 mingw-w64.org…...
(四)PostgreSQL数据库操作示例
删除有外键约束的表 最近做数据库练习遇到一个问题,数据库里面有一个表,存在外键约束,我想要删除,所以必须先删除这些外键约束。 查询外键约束 查找外键约束:当你需要知道某个表的外键约束及其引用关系时࿰…...

Docker-微服务项目部署
环境准备 1.微服务项目 参考:通过网盘分享的文件:wolf2w_cloud.zip 链接: https://pan.baidu.com/s/1Lr4k6LPIJ59gVNA_DgKM_Q?pwdkjxt 提取码: kjxt 前端项目:trip-mgrsite-ui,trip-website-ui,trip-wenda-ui 服务项…...
测试Bug提交报告模板
撰写测试Bug提交说明时,清晰、详细和准确是至关重要的。这有助于开发团队快速理解问题、重现Bug并修复它。以下是一个测试Bug提交说明的模板,可以根据实际情况进行调整: 测试Bug提交说明 1. Bug基本信息 Bug编号:[系统自动生成…...

MybatisPlus - 核心功能
文章目录 1.MybatisPlus实现基本的CRUD快速开始常见注解常见配置 2.使用条件构建造器构建查询和更新语句条件构造器自定义SQLService接口 官网 MybatisPlus无侵入和方便快捷. MybatisPlus不仅仅可以简化单表操作,而且还对Mybatis的功能有很多的增强。可以让我们的开…...

小柴冲刺软考中级嵌入式系统设计师系列二、嵌入式系统硬件基础知识(6)嵌入式系统总线及通信接口
目录 越努力,越幸运! flechazo 小柴冲刺软考中级嵌入式系统设计师系列总目录 一、PCI、PCI-E 等接口基本原理与结构 1、PCI (1)高速性。 (2)即插即用性。 (3)可靠性。 (4)复杂性。 (5)自动配置。 (6)共享中断。 (7)扩展性好。 (8)多路复用。…...
利用字典对归一化后的数据0误差还原
假设我对精度要求很高,高到无法容忍有任何误差,那么我先将x按照大小排序,然后归一化,用字典将归一化前后的x存储下来,在深度学习时使用归一化后的x进行处理,但是最后画图等处理时,我用字典取出归…...

HarmonyOS:UIAbility组件概述
一、概述 UIAbility组件是一种包含UI的应用组件,主要用于和用户交互。 UIAbility的设计理念: 原生支持应用组件级的跨端迁移和多端协同。支持多设备和多窗口形态。 UIAbility划分原则与建议: UIAbility组件是系统调度的基本单元,…...

12寸半导体厂说的华夫区是什么意思
1\什么是华夫板 在半导体行业中,“华夫区”通常指的是“华夫板”(Waffle Slab),这是一种特殊设计的楼板,其表面具有许多均匀分布的孔洞,这些孔洞形成了回风通道,用于电子芯片厂房等对空气洁净度有极高要求的环境。华夫板的设计和施工对于保证洁净室的功能发挥至关重要。…...

数据结构之链式结构二叉树的实现(进阶版)
本篇文章主要讲解链式二叉树的层序遍历以及判断是否为一棵完全二叉树 二者将会用到之前学过的队列知识,是将队列和二叉树的整合 一、如何将之前已经写好的文件加入当前的编译界面 如图所示,打开我们需要加入文件所在的文件夹,找到我们要加…...
【高等数学】3-2多元函数积分学
1. 二重积分 可以想象你有一块不规则的平面薄板,它在一个平面区域上。二重积分就是用来求这个薄板的质量(假设薄板的面密度函数是)。 把区域划分成许多非常小的小方块(类似于把一块地划分成很多小格子),在每个小方块上,密度近似看成是一个常数,然后把每个小方块的质量加…...

【传知代码】智慧医疗:纹理特征VS卷积特征
🍑个人主页:Jupiter. 🚀 所属专栏:传知代码 欢迎大家点赞收藏评论😊 目录 论文概述纹理特征和深度卷积特征算法流程数据预处理方法纹理特征提取深度卷积特征提取分类网络搭建代码复现BLS_Model.py文件——分类器搭建py…...

Python-创建并调用自定义文件中的模块/函数
背景:在Python编程中,我们常常需要创建自己的专属文件,以便帮助我们更高效,快捷地完成任务。那么在Python中我们怎么创建并调用自己文件中的模块/函数呢? 在Python中调用自定义文件,通常是指调用自己编写的Python模块…...

Kali Linux
起源与背景 Kali Linux是一个基于Debian的开源Linux发行版,专门为信息安全工作者和渗透测试员设计。它是由Offensive Security Ltd.开发和维护的,作为BackTrack的继承者而诞生。BackTrack是一个流行的安全测试发行版,但为了提供更好的支持和…...

DiffusionDet: Diffusion Model for Object Detection—用于对象检测的扩散模型论文解析
DiffusionDet: Diffusion Model for Object Detection—用于对象检测的扩散模型论文解析 这是一篇发表在CVPR 2023的一篇论文,因为自己本身的研究方向是目标跟踪,之前看了一点使用扩散模型进行多跟踪的论文,里面提到了DiffusionDet因此学习一…...

深度学习基础知识-编解码结构理论超详细讲解
编解码结构(Encoder-Decoder)是一种应用广泛且高效的神经网络架构,最早用于序列到序列(Seq2Seq)任务,如机器翻译、图像生成、文本生成等。随着深度学习的发展,编解码结构不断演变出多种模型变体…...
探讨Java深搜算法的学习笔记
大家好,我是 V 哥。深度优先搜索(DFS)是一种图遍历算法,它优先深入到某条路径的尽头,再回溯到前一个节点继续探索其他路径,直到找到目标或遍历完整个图。DFS的应用场景广泛,可以用于路径搜索、连…...
408——操作系统(持续更新)
文章目录 一、操作系统的概念及特征1.1 计算机系统的概念1.2 操作系统的基本特征 二、操作系统的功能和接口2.1 操作系统作为计算机资源的管理者2.2 操作系统作为用户和计算机硬件系统之间的接口2.3 操作系统实现对计算机资源的扩充 三、操作系统的发展和分类四、操作系统的运行…...
架构师之路-学渣到学霸历程-37
Nginx的热部署实验 本次分享的就是nginx的升级以及降级,实验中其实很多操作都需要理解,实际操作不难,但是需要全面理解这个动作,敲这个命令是用来干什么的?借着这个笔记可以试一下;go~! 1、ng…...

CSRF与SSRF
csrf(跨站请求伪造)的原理: csrf全称是跨站请求伪造(cross-site request forgery),也被称为one-click attack 或者 session riding scrf攻击利用网站对于用户网页浏览器的信任,劫持用户当前已登录的web应用程序,去执行分用户本意的操作。 利…...