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

Qt+C++串口调试接收发送数据曲线图

程序示例精选

Qt+C++串口调试接收发送数据曲线图

如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助!

前言

这篇博客针对<<Qt+C++串口调试接收发送数据曲线图>>编写代码,代码整洁,规则,易读。 学习与应用推荐首选。


文章目录

一、所需工具软件

二、使用步骤

        1. 引入库

        2. 代码实现

        3. 运行结果

三、在线协助

一、所需工具软件

1. VS, Qt

2. C++

二、使用步骤

1.引入库

#include <QAction>
#include <QCheckBox>
#include <QDragEnterEvent>
#include <QDebug>
#include <QLineEdit>
#include <QMenu>
#include <QMenuBar>
#include <QtSerialPort/QSerialPort>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QGroupBox>
#include <QTextBrowser>
#include <QtWidgets/QFileDialog>
#include <QTimer>
#include <QtCore/QSettings>
#include <QtCore/QProcess>
#include <QStatusBar>
#include <QSplitter>
#include <data/SerialReadWriter.h>
#include <data/TcpServerReadWriter.h>
#include <data/TcpClientReadWriter.h>
#include <QRadioButton>
#include <QButtonGroup>
#include <data/BridgeReadWriter.h>
#include <QMimeData>
#include <QtSerialPort/QSerialPortInfo>
#include <data/SerialBridgeReadWriter.h>
#include <utils/FileUtil.h>
#include <QTextCodec>

2. 代码实现

代码如下:

void MainWindow::openReadWriter() {if (_readWriter != nullptr) {_readWriter->close();delete _readWriter;_readWriter = nullptr;emit serialStateChanged(false);}bool result;if (readWriterButtonGroup->checkedButton() == serialRadioButton) {_serialType = SerialType::Normal;auto settings = new SerialSettings();settings->name = serialPortNameComboBox->currentText();settings->baudRate = serialPortBaudRateComboBox->currentText().toInt();settings->dataBits = (QSerialPort::DataBits) serialPortDataBitsComboBox->currentText().toInt();settings->stopBits = (QSerialPort::StopBits) serialPortStopBitsComboBox->currentData().toInt();settings->parity = (QSerialPort::Parity) serialPortParityComboBox->currentData().toInt();auto readWriter = new SerialReadWriter(this);readWriter->setSerialSettings(*settings);qDebug() << settings->name << settings->baudRate << settings->dataBits << settings->stopBits<< settings->parity;result = readWriter->open();if (!result) {showWarning(tr("消息"), tr("串口被占用或者不存在"));return;}_readWriter = readWriter;_serialType = SerialType::Normal;} else if (readWriterButtonGroup->checkedButton() == tcpServerRadioButton) {_serialType = SerialType::TcpServer;auto address = tcpAddressLineEdit->text();bool ok;auto port = tcpPortLineEdit->text().toInt(&ok);if (!ok) {showMessage("", tr("端口格式不正确"));return;}auto readWriter = new TcpServerReadWriter(this);readWriter->setAddress(address);readWriter->setPort(port);qDebug() << address << port;result = readWriter->open();if (!result) {showWarning("", tr("建立服务器失败"));return;}connect(readWriter, &TcpServerReadWriter::currentSocketChanged, this, &MainWindow::updateTcpClient);connect(readWriter, &TcpServerReadWriter::connectionClosed, this, &MainWindow::clearTcpClient);_readWriter = readWriter;} else if (readWriterButtonGroup->checkedButton() == tcpClientRadioButton) {_serialType = SerialType::TcpClient;auto address = tcpAddressLineEdit->text();bool ok;auto port = tcpPortLineEdit->text().toInt(&ok);if (!ok) {showMessage("", tr("端口格式不正确"));return;}auto readWriter = new TcpClientReadWriter(this);readWriter->setAddress(address);readWriter->setPort(port);qDebug() << address << port;result = readWriter->open();if (!result) {showError("", tr("连接服务器失败"));return;}_readWriter = readWriter;} else if (readWriterButtonGroup->checkedButton() == serialBridgeRadioButton) {_serialType = SerialType::SerialBridge;auto settings1 = new SerialSettings();settings1->name = serialPortNameComboBox->currentText();settings1->baudRate = serialPortBaudRateComboBox->currentText().toInt();settings1->dataBits = (QSerialPort::DataBits) serialPortDataBitsComboBox->currentText().toInt();settings1->stopBits = (QSerialPort::StopBits) serialPortStopBitsComboBox->currentData().toInt();settings1->parity = (QSerialPort::Parity) serialPortParityComboBox->currentData().toInt();auto settings2 = new SerialSettings();settings2->name = secondSerialPortNameComboBox->currentText();settings2->baudRate = secondSerialPortBaudRateComboBox->currentText().toInt();settings2->dataBits = (QSerialPort::DataBits) secondSerialPortDataBitsComboBox->currentText().toInt();settings2->stopBits = (QSerialPort::StopBits) secondSerialPortStopBitsComboBox->currentText().toInt();settings2->parity = (QSerialPort::Parity) secondSerialPortParityComboBox->currentText().toInt();auto readWriter = new SerialBridgeReadWriter(this);readWriter->setSettings(*settings1, *settings2);result = readWriter->open();if (!result) {showWarning(tr("消息"), QString(tr("串口被占用或者不存在,%1")).arg(readWriter->settingsText()));return;}connect(readWriter, &SerialBridgeReadWriter::serial1DataRead, [this](const QByteArray &data) {showSendData(data);});connect(readWriter, &SerialBridgeReadWriter::serial2DataRead, [this](const QByteArray &data) {showReadData(data);});_readWriter = readWriter;} else {_serialType = SerialType::Bridge;auto settings = new SerialSettings();settings->name = serialPortNameComboBox->currentText();settings->baudRate = serialPortBaudRateComboBox->currentText().toInt();settings->dataBits = (QSerialPort::DataBits) serialPortDataBitsComboBox->currentText().toInt();settings->stopBits = (QSerialPort::StopBits) serialPortStopBitsComboBox->currentData().toInt();settings->parity = (QSerialPort::Parity) serialPortParityComboBox->currentData().toInt();auto address = tcpAddressLineEdit->text();bool ok;auto port = tcpPortLineEdit->text().toInt(&ok);if (!ok) {showMessage("", tr("端口格式不正确"));return;}auto readWriter = new BridgeReadWriter(this);readWriter->setSettings(*settings, address, static_cast<qint16>(port));result = readWriter->open();if (!result) {showWarning(tr("消息"), tr("串口被占用或者不存在"));return;}connect(readWriter, &BridgeReadWriter::currentSocketChanged,this, &MainWindow::updateTcpClient);connect(readWriter, &BridgeReadWriter::connectionClosed,this, &MainWindow::clearTcpClient);connect(readWriter, &BridgeReadWriter::serialDataRead, [this](const QByteArray &data) {showSendData(data);});connect(readWriter, &BridgeReadWriter::tcpDataRead, [this](const QByteArray &data) {showReadData(data);});_readWriter = readWriter;}connect(_readWriter, &AbstractReadWriter::readyRead,this, &MainWindow::readData);emit serialStateChanged(result);
}void MainWindow::closeReadWriter() {stopAutoSend();if (_readWriter != nullptr) {_readWriter->close();delete _readWriter;_readWriter = nullptr;}emit serialStateChanged(false);
}void MainWindow::createConnect() {connect(readWriterButtonGroup, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled),[=](QAbstractButton *button, bool checked) {if (checked && isReadWriterOpen()) {SerialType serialType;if (button == tcpServerRadioButton) {serialType = SerialType::TcpServer;} else if (button == tcpClientRadioButton) {serialType = SerialType::TcpClient;} else if (button == bridgeRadioButton) {serialType = SerialType::Bridge;} else {serialType = SerialType::Normal;}if (serialType != _serialType) {if (showWarning("", tr("串口配置已经改变,是否重新打开串口?"))) {openReadWriter();}}}});connect(this, &MainWindow::serialStateChanged, [this](bool isOpen) {setOpenButtonText(isOpen);QString stateText;if (isOpen) {stateText = QString(tr("串口打开成功,%1")).arg(_readWriter->settingsText());} else {stateText = QString(tr("串口关闭"));}skipSendCount = 0;updateStatusMessage(stateText);});connect(this, &MainWindow::readBytesChanged, this, &MainWindow::updateReadBytes);connect(this, &MainWindow::writeBytesChanged, this, &MainWindow::updateWriteBytes);connect(this, &MainWindow::currentWriteCountChanged, this, &MainWindow::updateCurrentWriteCount);connect(openSerialButton, &QPushButton::clicked, [=](bool value) {if (!isReadWriterOpen()) {openReadWriter();} else {closeReadWriter();}});connect(refreshSerialButton, &QPushButton::clicked, [=] {_dirty = true;updateSerialPortNames();});connect(saveReceiveDataButton, &QPushButton::clicked, this, &MainWindow::saveReceivedData);connect(clearReceiveDataButton, &QPushButton::clicked, this, &MainWindow::clearReceivedData);connect(saveSentDataButton, &QPushButton::clicked, this, &MainWindow::saveSentData);connect(clearSentDataButton, &QPushButton::clicked, this, &MainWindow::clearSentData);connect(autoSendCheckBox, &QCheckBox::clicked, [this] {autoSendTimer->stop();});connect(loopSendCheckBox, &QCheckBox::stateChanged, [this] {_loopSend = loopSendCheckBox->isChecked();});connect(resetLoopSendButton, &QPushButton::clicked, [this] {skipSendCount = 0;serialController->setCurrentCount(0);emit currentWriteCountChanged(0);});connect(currentSendCountLineEdit, &QLineEdit::editingFinished, [this] {bool ok;auto newCount = currentSendCountLineEdit->text().toInt(&ok);if (ok) {serialController->setCurrentCount(newCount);} else {currentSendCountLineEdit->setText(QString::number(serialController->getCurrentCount()));}});connect(sendLineButton, &QPushButton::clicked, [this] {if (!isReadWriterConnected()) {handlerSerialNotOpen();return;}if (autoSendState == AutoSendState::Sending) {stopAutoSend();} else {if (_dirty) {_dirty = false;_sendType = SendType::Line;updateSendData(hexCheckBox->isChecked(), sendTextEdit->toPlainText());updateSendType();}sendNextData();startAutoSendTimerIfNeed();}if (autoSendState == AutoSendState::Sending) {sendLineButton->setText(tr("停止"));} else {resetSendButtonText();}});connect(processTextButton, &QPushButton::clicked, [this] {openDataProcessDialog(sendTextEdit->toPlainText());});connect(clearTextButton, &QPushButton::clicked, [this]{sendTextEdit->clear();});connect(lineReturnButtonGroup, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled),[=](QAbstractButton *button, bool checked) {if (checked) {if (button == sendRReturnLineButton) {lineReturn = QByteArray("\r");} else if (button == sendNReturnLineButton) {lineReturn = QByteArray("\n");} else {lineReturn = QByteArray("\r\n");}}});connect(autoSendTimer, &QTimer::timeout,[this] {sendNextData();});connect(hexCheckBox, &QCheckBox::stateChanged, [this] {this->_dirty = true;});connect(sendTextEdit, &QTextEdit::textChanged, [this] {this->_dirty = true;});
}void MainWindow::setOpenButtonText(bool isOpen) {if (isOpen) {openSerialButton->setText(tr("关闭"));} else {openSerialButton->setText("打开");}
}void MainWindow::createActions() {openAct = new QAction(tr("&打开(&O)"), this);openAct->setShortcut(QKeySequence::Open);openAct->setStatusTip(tr("打开一个文件"));connect(openAct, &QAction::triggered, this, &MainWindow::open);saveAct = new QAction(tr("&保存(&S)"), this);saveAct->setShortcut(QKeySequence::Save);saveAct->setStatusTip(tr("保存一个文件"));connect(saveAct, &QAction::triggered, this, &MainWindow::save);validateDataAct = new QAction(tr("计算校验(&E)"), this);validateDataAct->setShortcut(tr("Ctrl+E"));validateDataAct->setStatusTip(tr("计算数据校验值"));connect(validateDataAct, &QAction::triggered, this, &MainWindow::openDataValidator);convertDataAct = new QAction(tr("数据转换(&T)"));convertDataAct->setShortcut(tr("Ctrl+T"));convertDataAct->setStatusTip(tr("数据转换"));connect(convertDataAct, &QAction::triggered, this, &MainWindow::openConvertDataDialog);dataProcessAct = new QAction(tr("数据处理(&P)"));dataProcessAct->setShortcut(tr("Ctrl+P"));dataProcessAct->setStatusTip(tr("数据处理"));connect(dataProcessAct, &QAction::triggered, [this] {openDataProcessDialog("");});
}void MainWindow::createMenu() {fileMenu = menuBar()->addMenu(tr("文件(&F)"));fileMenu->addAction(openAct);fileMenu->addAction(saveAct);toolMenu = menuBar()->addMenu(tr("工具(&T)"));toolMenu->addAction(validateDataAct);toolMenu->addAction(convertDataAct);toolMenu->addAction(dataProcessAct);
}void MainWindow::open() {auto lastDir = runConfig->lastDir;QString fileName = QFileDialog::getOpenFileName(this, tr("打开数据文件"), lastDir, "");if (fileName.isEmpty()) {return;}QFile file(fileName);if (file.open(QIODevice::ReadOnly)) {runConfig->lastDir = getFileDir(fileName);auto data = file.readAll();sendTextEdit->setText(QString::fromLocal8Bit(data));}
}void MainWindow::save() {saveReceivedData();
}void MainWindow::openDataValidator() {CalculateCheckSumDialog dialog(this);dialog.setModal(true);dialog.exec();
}void MainWindow::openConvertDataDialog() {ConvertDataDialog dialog(this);dialog.setModal(true);dialog.exec();
}void MainWindow::openDataProcessDialog(const QString &text) {DataProcessDialog dialog(text, this);dialog.setModal(true);int result = dialog.exec();if (result == QDialog::Accepted) {sendTextEdit->setText(dialog.text());}
}void MainWindow::displayReceiveData(const QByteArray &data) {if (pauseReceiveCheckBox->isChecked()) {return;}static QString s;s.clear();if (addReceiveTimestampCheckBox->isChecked()) {s.append("[").append(getTimestamp()).append("] ");}if (!s.isEmpty()) {s.append(" ");}if (displayReceiveDataAsHexCheckBox->isChecked()) {s.append(dataToHex(data));} else {s.append(QString::fromLocal8Bit(data));}if (addLineReturnCheckBox->isChecked() || addReceiveTimestampCheckBox->isChecked()) {receiveDataBrowser->append(s);} else {auto text = receiveDataBrowser->toPlainText();text.append(s);receiveDataBrowser->setText(text);receiveDataBrowser->moveCursor(QTextCursor::End);}
}void MainWindow::displaySentData(const QByteArray &data) {if (displaySendDataAsHexCheckBox->isChecked()) {sendDataBrowser->append(dataToHex(data));} else {sendDataBrowser->append(QString::fromLocal8Bit(data));}
}void MainWindow::sendNextData() {if (isReadWriterConnected()) {if (skipSendCount > 0) {auto delay = skipSendCount * sendIntervalLineEdit->text().toInt();updateStatusMessage(QString("%1毫秒后发送下一行").arg(delay));skipSendCount--;return;}qDebug() << "sendNextData readEnd:" << serialController->readEnd() << "current:"<< serialController->getCurrentCount();if (!_loopSend && autoSendCheckBox->isChecked() && serialController->readEnd()) {serialController->setCurrentCount(0);stopAutoSend();return;}auto data = serialController->readNextFrame();if (data.isEmpty()) {updateStatusMessage(tr("空行,不发送"));if (autoSendCheckBox->isChecked()) {auto emptyDelay = emptyLineDelayLindEdit->text().toInt();auto sendInterval = sendIntervalLineEdit->text().toInt();if (emptyDelay > sendInterval) {skipSendCount = emptyDelay / sendInterval;if (emptyDelay % sendInterval != 0) {skipSendCount += 1;}skipSendCount--;updateStatusMessage(QString(tr("空行,%1毫秒后发送下一行")).arg(emptyDelay));}}emit currentWriteCountChanged(serialController->getCurrentCount());return;}writeData(data);if (sendLineReturnCheckBox->isChecked()) {writeData(lineReturn);}if (hexCheckBox->isChecked()) {updateStatusMessage(QString(tr("发送 %1")).arg(QString(dataToHex(data))));} else {updateStatusMessage(QString(tr("发送 %1")).arg(QString(data)));}emit currentWriteCountChanged(serialController->getCurrentCount());} else {handlerSerialNotOpen();}
}void MainWindow::updateSendData(bool isHex, const QString &text) {if (serialController != nullptr) {QStringList lines = getLines(text);QList<QByteArray> dataList;if (isHex) {for (auto &line :lines) {dataList << dataFromHex(line);}} else {for (auto &line:lines) {dataList << line.toLocal8Bit();}}serialController->setData(dataList);totalSendCount = serialController->getTotalCount();updateTotalSendCount(totalSendCount);}
}void MainWindow::readSettings() {qDebug() << "readSettings";updateSerialPortNames();QSettings settings("Zhou Jinlong", "Serial Wizard");settings.beginGroup("Basic");auto serialType = SerialType(settings.value("serial_type", static_cast<int >(SerialType::Normal)).toInt());if (serialType == SerialType::TcpServer) {tcpServerRadioButton->setChecked(true);} else if (serialType == SerialType::TcpClient) {tcpClientRadioButton->setChecked(true);} else if (serialType == SerialType::Bridge) {bridgeRadioButton->setChecked(true);} else if (serialType == SerialType::SerialBridge) {serialBridgeRadioButton->setChecked(true);} else {serialRadioButton->setChecked(true);}_serialType = serialType;settings.beginGroup("SerialSettings");auto nameIndex = settings.value("name", 0).toInt();auto baudRateIndex = settings.value("baud_rate", 5).toInt();auto dataBitsIndex = (QSerialPort::DataBits) settings.value("data_bits", 3).toInt();auto stopBitsIndex = (QSerialPort::StopBits) settings.value("stop_bits", 0).toInt();auto parityIndex = (QSerialPort::Parity) settings.value("parity", 0).toInt();auto sendText = settings.value("send_text", "").toString();auto maxCount = serialPortNameComboBox->maxCount();if (nameIndex > maxCount - 1) {nameIndex = 0;}serialPortNameComboBox->setCurrentIndex(nameIndex);serialPortBaudRateComboBox->setCurrentIndex(baudRateIndex);serialPortDataBitsComboBox->setCurrentIndex(dataBitsIndex);serialPortStopBitsComboBox->setCurrentIndex(stopBitsIndex);serialPortParityComboBox->setCurrentIndex(parityIndex);auto name2Index = settings.value("name2", 0).toInt();auto baudRate2Index = settings.value("baud_rate2", 5).toInt();auto dataBits2Index = (QSerialPort::DataBits) settings.value("data_bits2", 3).toInt();auto stopBits2Index = (QSerialPort::StopBits) settings.value("stop_bits2", 0).toInt();auto parity2Index = (QSerialPort::Parity) settings.value("parity2", 0).toInt();auto maxCount2 = serialPortNameComboBox->maxCount();if (name2Index > maxCount2 - 1) {name2Index = 0;}secondSerialPortNameComboBox->setCurrentIndex(name2Index);secondSerialPortBaudRateComboBox->setCurrentIndex(baudRate2Index);secondSerialPortDataBitsComboBox->setCurrentIndex(dataBits2Index);secondSerialPortStopBitsComboBox->setCurrentIndex(stopBits2Index);secondSerialPortParityComboBox->setCurrentIndex(parity2Index);settings.beginGroup("SerialReceiveSettings");auto addLineReturn = settings.value("add_line_return", true).toBool();auto displayReceiveDataAsHex = settings.value("display_receive_data_as_hex", false).toBool();auto addTimestamp = settings.value("add_timestamp", false).toBool();addLineReturnCheckBox->setChecked(addLineReturn);displayReceiveDataAsHexCheckBox->setChecked(displayReceiveDataAsHex);addReceiveTimestampCheckBox->setChecked(addTimestamp);settings.beginGroup("SerialSendSettings");auto sendAsHex = settings.value("send_as_hex", false).toBool();auto displaySendData = settings.value("display_send_data", false).toBool();auto displaySendDataAsHex = settings.value("display_send_data_as_hex", false).toBool();auto autoSend = settings.value("auto_send", false).toBool();auto autoSendInterval = settings.value("auto_send_interval", 100).toInt();auto emptyLineDelay = settings.value("empty_line_delay", 0).toInt();auto loopSend = settings.value("loop_send", false).toBool();hexCheckBox->setChecked(sendAsHex);displaySendDataCheckBox->setChecked(displaySendData);displaySendDataAsHexCheckBox->setChecked(displaySendDataAsHex);autoSendCheckBox->setChecked(autoSend);loopSendCheckBox->setChecked(loopSend);sendIntervalLineEdit->setText(QString::number(autoSendInterval));emptyLineDelayLindEdit->setText(QString::number(emptyLineDelay));auto sendLineReturn = settings.value("send_line_return", false).toBool();sendLineReturnCheckBox->setChecked(sendLineReturn);auto sendLineReturnType = LineReturn(settings.value("send_line_return_type", static_cast<int >(LineReturn::RN)).toInt());if (sendLineReturnType == LineReturn::R) {sendRReturnLineButton->setChecked(true);} else if (sendLineReturnType == LineReturn::N) {sendNReturnLineButton->setChecked(true);} else {sendRNLineReturnButton->setChecked(true);}settings.beginGroup("TcpSettings");auto ipList = getNetworkInterfaces();auto ipAddress = settings.value("tcp_address", "").toString();QString selectAddress = "";if (!ipAddress.isEmpty() && !ipList.isEmpty()) {auto found = false;for (const auto &ip:ipList) {if (getIpAddress(ip) == ipAddress) {selectAddress = ipAddress;found = true;break;}}if (!found) {selectAddress = getIpAddress(ipList.first());}}if (selectAddress.isEmpty()) {if (!ipList.isEmpty()) {do {for (const auto &ip:ipList) {if (ip.type() == QNetworkInterface::Wifi && !getIpAddress(ip).isEmpty()) {selectAddress = getIpAddress(ip);break;}}if (!selectAddress.isEmpty()) {break;}for (const auto &ip:ipList) {if (ip.type() == QNetworkInterface::Ethernet && !getIpAddress(ip).isEmpty()) {selectAddress = getIpAddress(ip);}}if (!selectAddress.isEmpty()) {break;}selectAddress = getIpAddress(ipList.first());} while (false);}}tcpAddressLineEdit->setText(selectAddress);auto tcpPort = settings.value("tcp_port").toInt();tcpPortLineEdit->setText(QString::number(tcpPort));sendTextEdit->setText(sendText);settings.beginGroup("RunConfig");auto lastDir = settings.value("last_dir", "").toString();auto lastFilePath = settings.value("last_file_path", "").toString();runConfig = new RunConfig;runConfig->lastDir = lastDir;runConfig->lastFilePath = lastFilePath;_loopSend = loopSend;serialController = new LineSerialController();updateSendType();
}

3. 运行结果

动画演示

 

三、在线协助:

如需安装运行环境或远程调试,见文章底部个人 QQ 名片,由专业技术人员远程协助!
1)远程安装运行环境,代码调试
2)Qt, C++, Python入门指导
3)界面美化
4)软件制作

当前文章连接:Python+Qt桌面端与网页端人工客服沟通工具_alicema1111的博客-CSDN博客

博主推荐文章:python人脸识别统计人数qt窗体-CSDN博客

博主推荐文章:Python Yolov5火焰烟雾识别源码分享-CSDN博客

                         Python OpenCV识别行人入口进出人数统计_python识别人数-CSDN博客

个人博客主页:alicema1111的博客_CSDN博客-Python,C++,网页领域博主

博主所有文章点这里alicema1111的博客_CSDN博客-Python,C++,网页领域博主

相关文章:

Qt+C++串口调试接收发送数据曲线图

程序示例精选 QtC串口调试接收发送数据曲线图 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<QtC串口调试接收发送数据曲线图>>编写代码&#xff0c;代码整洁&#xff0c;规则&…...

【从零学习python 】75. TCP协议:可靠的面向连接的传输层通信协议

文章目录 TCP协议TCP通信的三个步骤TCP特点TCP与UDP的区别TCP通信模型进阶案例 TCP协议 TCP协议&#xff0c;传输控制协议&#xff08;英语&#xff1a;Transmission Control Protocol&#xff0c;缩写为 TCP&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议…...

IPv4 基础概念

IPv4 基础概念 IPv4 广播地址 广播是一种通信方式&#xff0c;用于将数据包发送到同一网络中的所有设备。在广播中&#xff0c;数据包被发送到特殊的广播地址&#xff0c;例如在IPv4中&#xff0c;广播地址通常为特定子网的广播地址&#xff08;例如&#xff0c;192.168.1.0/…...

stm32片内读写项目总结(多字节读写tongxindu)

1.flash操作驱动程序 a头文件 #ifndef FLASH_H #define FLASH_H #include “stm32f4xx.h” #define BOARD_NUM_ADDR 0x0800C000 #define STM32_FLASH_BASE 0x08000000 //STM32 FLASH的起始地址 #define FLASH_WAITETIME 50000 //FLASH等待超时时间 //FLASH 扇区的起始地址…...

ECMAScript6 简介及拓展

ECMAScript简介 JavaScript是大家所了解的语言名称&#xff0c; 但它的正式名称叫做ECMAScript。 1996年11月&#xff0c; JavaScript的创造者网景公司将JavaScript提交给国际化组织 ECMA(欧洲计算机制造联合会)&#xff0c; 希望这种语言能够成为国际标准。 随后 ECMA 发布…...

可视化构建包分析报告

一、webpack 使用 webpack-bundle-analyzer 插件即可。 安装&#xff1a;npm install webpack-bundle-analyzer -D 使用&#xff1a;new BundleAnalyzerPlugin(options?: object) Name Type Description analyzerMode One of: server, static, json, disabled Default: se…...

统一git使用方法,git状态变迁图,git commit提交规范

目录 说明 统一git使用方法 git状态变迁图 git commit 提交规范 说明 多次工作中多名员工不懂git多次技术分享&#xff0c;自行查资料学习git并使用&#xff0c;会出现使用各种偏僻的命令&#xff0c;异常问题无法解决&#xff1b;或出现带url的git合并提交。主要是学的不…...

react与vue的区别

React和Vue.js是两个流行的JavaScript库/框架&#xff0c;用于构建用户界面。以下是React和Vue之间的一些主要区别&#xff1a; 学习曲线&#xff1a;Vue.js对于新手来说比React更容易学习和上手。 构建方式&#xff1a;React强调组件的可重用性&#xff0c;而Vue.js更注重模板…...

成功解决SQL 错误 [22000]: 第3 行附近出现错误: 试图修改自增列[ID](达梦数据库)

当我们使用工具来手动修改自增列的自增ID时&#xff0c;可能会报如下异常 SQL 错误 [22000]: 第3 行附近出现错误:试图修改自增列[ID] 解决办法&#xff1a; 可以使用SQL语句来修改 ALTER TABLE "fdw"."SYSTEM_DICT_TYPE" DROP IDENTITY; UPDATE "f…...

【算法】活用双指针完成复写零操作

Problem: 1089. 复写零 文章目录 题目解析算法原理分析找到最后一个复写的位置从后往前进行复写操作 代码展示 题目解析 首先我们来分析一下本题的题目意思 可以看到题目中给到了一个数组&#xff0c;意思是让我们将数组中的零元素都复写一遍&#xff0c;然后将其余的元素向后平…...

【面试高频题】难度 3/5,字典树热门运用题

题目描述 这是 LeetCode 上的 「745. 前缀和后缀搜索」 &#xff0c;难度为 「困难」。 Tag : 「字典树」 设计一个包含一些单词的特殊词典&#xff0c;并能够通过前缀和后缀来检索单词。 实现 WordFilter 类&#xff1a; WordFilter(string[] words) 使用词典中的单词 words 初…...

vue base64图片转file流 下载到本地 或者上传

<img :src"data:image/png;base64,form.img" style"max-width:280px;max-height: 280px;margin: auto;" />// base64 转file const base64ToFile()>{let byImg atob(form.img); // 解码base64let n byImg.lengthlet a new Uint8Array(n);while…...

无涯教程-PHP - 简介

PHP 7是最期待的&#xff0c;它是PHP编程语言的主要功能版本。 PHP 7于2015年12月3日发布。本教程将以简单直观的方式教您PHP 7的新功能及其用法。 无涯教程假设您已经了解旧版本的PHP&#xff0c;现在就可以开始学习PHP 7的新功能。 使用下面的示例- <html><head&…...

web基础+HTTP协议+httpd详细配置

目目录录 一、Web基础1.1 HTML概述1.1.1 HTML的文件结构1.1.2 HTML中的部分基本标签 1.3 MIME1.4 URI 和 URL1.4 定义1.4.2 URI 和 URL 的区别 二、静态资源和动态资源2.1 静态资源2.2 动态资源 三、HTTP协议3.1 HTTP协议简介3.2 HTTP协议版本3.2 HTTP方法3.3 HTTP请求访问的完…...

【sql】MongoDB的增删改查分页条件等

【sql】MongoDB的增删改查分页条件等 //增 //新增数据2种方式 db.msg.save({"name":"springboot&#x1f600;"}); db.msg.insert({"name":"mango good"}); db.msg.save({"name":"springboot",type:"工具书&…...

我的动态归纳(便于搜索)

linux dns配置文件是“/etc/resolv.conf”&#xff0c;该配置文件用于配置DNS客户&#xff0c;它包含了主机的域名搜索顺序和DNS/服务器的地址&#xff0c;每一行包括一个关键字和一个或多个空格隔开的参数。 /etc/resolv.conf &#xff08;不配置就不能域名解析&#xff09; 可…...

langchain ChatGPT AI私有知识库

企业知识库 原理就是把文档变为向量数据库&#xff0c;然后搜索向量数据库&#xff0c;把相似的数据和问题作为prompt&#xff0c; 输入到大模型&#xff0c;再利用GPT强大的自然语言处理、推理和分析等方面的能力将答案返回给用户 什么是langchain? langchain是一个强大的…...

API接口常用数据格式Json,Json的定义和XML的区别

现在程序员还有谁不知道 JSON 吗&#xff1f;无论对于前端还是后端&#xff0c;JSON 都是一种常见的数据格式。那么 JSON 到底是什么呢&#xff1f; JSON 的定义 JSON &#xff08;JavaScript Object Notation&#xff09; &#xff0c;是一种轻量级的数据交换格式。它的使用…...

密码学学习笔记(二十一):SHA-256与HMAC、NMAC、KMAC

SHA-256 SHA-2是广泛应用的哈希函数&#xff0c;并且有不同的版本&#xff0c;这篇博客主要介绍SHA-256。 SHA-256算法满足了哈希函数的三个安全属性&#xff1a; 抗第一原像性 - 无法根据哈希函数的输出恢复其对应的输入。抗第二原像性 - 给定一个输入和它的哈希值&#xf…...

操作系统-笔记-第四章-文件管理

目录 四、第四章——文件管理 1、文件管理——基础概念 &#xff08;1&#xff09;文件结构 &#xff08;2&#xff09;操作系统提供的接口 &#xff08;3&#xff09;总结 2、文件的逻辑结构 &#xff08;1&#xff09;有结构文件&#xff08;类似SQL表文件&#xff09…...

【MiniGUI】文字颜色实现透明度变化

在MiniGUi中&#xff0c;输出文字时有时候希望文字带有透明度信息&#xff0c; 即文字能够透出下面的图像来。 很自然地想到&#xff0c;设置颜色时&#xff0c;将颜色设置为带有透明度的颜色&#xff1a; SelectFont(hdc, mg_font);SetTextColor(hdc, RGBA2Pixel(HDC_SCREEN, …...

css中元素加定位之后到一定距离元素会变小

css中元素加定位之后到一定距离元素会变小 主要原因&#xff1a;元素没有加宽高 .swiperWrapper .active{bottom: 380px;left: 215px;z-index: 10; } .swiperWrapper .next{bottom: 170px;left: 7%;z-index: 20; } .swiperWrapper .prev{bottom: 360px;left: 0%;z-index: 30;…...

Java 语言实现冒泡排序

Java 语言实现冒泡排序 介绍 冒泡排序是一种简单直观的排序算法&#xff0c;它重复地比较相邻的两个元素&#xff0c;如果顺序错误就交换它们&#xff0c;直到没有需要交换的元素为止。冒泡排序的思路是通过每一轮的比较将最大&#xff08;或最小&#xff09;的元素逐渐“冒泡…...

面向对象单选题

下列选项中不属于面向对象的特征的是&#xff08;B&#xff09; A、封装性 B、安全性 C、继承性 D、多态性 在Java中,关于继承&#xff0c;类只支持&#xff08;A&#xff09; A、单继承 B、多继承 C、两个都可以 D、两个都不可以 用于定义成员的访问控制权的一组关键字…...

微服务-Fegin

在之前我们两服务之间调用的时候用的是restTemplate,但是这个方式调用存在很多的问题 String url "http://userservice/user/" order.getUserId(); 代码可读性差&#xff0c;编码体验不统一参数复杂的url难以维护 所以我们大力推出我们今天的主角--Fegin Feign是…...

[oneAPI] 使用字符级 RNN 生成名称

[oneAPI] 使用字符级 RNN 生成名称 oneAPI特殊写法使用字符级 RNN 生成名称Intel Optimization for PyTorch数据下载加载数据并对数据进行处理创建网络训练过程准备训练训练网络 结果 参考资料 比赛&#xff1a;https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517…...

【ROS】参数服务器--理论模型与参数操作(C++)

一、概念介绍 参数服务器在ROS中主要用于实现不同节点之间的数据共享。参数服务器相当于是独立于所有节点的一个公共容器&#xff0c;可以将数据存储在该容器中&#xff0c;被不同的节点调用&#xff0c;当然不同的节点也可以往其中存储数据。 作用&#xff1a;存储一些多节点…...

[oneAPI] 基于BERT预训练模型的英文文本蕴含任务

[oneAPI] 基于BERT预训练模型的英文文本蕴含任务 Intel DevCloud for oneAPI 和 Intel Optimization for PyTorch基于BERT预训练模型的英文文本蕴含任务语料介绍数据集构建 模型训练 结果参考资料 比赛&#xff1a;https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0…...

【洛谷】P1163 银行贷款

原题链接&#xff1a;https://www.luogu.com.cn/problem/P1163 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 这题需要注意的是利率按月累计这句话&#xff0c;也就是相当于“利滚利”。 我们定义sum变量表示贷款原值&#xff0c;money表示每月支付…...

Java版工程行业管理系统源码-专业的工程管理软件-提供一站式服务 em

​ 鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工…...

kafka--技术文档--基本docker中安装<单机>-linux

安装zookeeper 阿丹小科普&#xff1a; Kafka在0.11.0.0版本之后不再依赖Zookeeper&#xff0c;而是使用基于Raft协议的Kafka自身的仲裁机制来替代Zookeeper。具体来说&#xff0c;Kafka 2.8.0版本是第一个不需要Zookeeper就可以运行Kafka的版本&#xff0c;这被称为Kafka Raf…...

回归预测 | MATLAB实现WOA-RF鲸鱼优化算法优化随机森林算法多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现WOA-RF鲸鱼优化算法优化随机森林算法多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现WOA-RF鲸鱼优化算法优化随机森林算法多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果一览…...

Linux系统安全——NAT(SNAT、DNAT)

目录 NAT SNAT SNAT实际操作 DNAT DNAT实际操作 NAT NAT: network address translation&#xff0c;支持PREROUTING&#xff0c;INPUT&#xff0c;OUTPUT&#xff0c;POSTROUTING四个链 请求报文&#xff1a;修改源/目标IP&#xff0c; 响应报文&#xff1a;修改源/目标…...

uniapp项目添加人脸识别功能,可用作登录,付款,流程审批前的安全校验

本案例使用了hbuilder插件商城中的活体检验插件&#xff0c;可自行前往作者处下载查看&#xff0c; 效果图如下 此插件需要在manifest.json中勾选 实现流程 1&#xff1a;前往hbuilder插件市场下载插件 2&#xff1a;在页面中导入import face from "/uni_modules/mcc-…...

SpringBoot面试题

Spring Boot的启动流程主要分为以下几个步骤&#xff1a; 加载Spring Boot配置文件&#xff0c;初始化Spring Boot环境和核心组件&#xff0c;如ApplicationContext上下文环境、自动装配机制等。 执行SpringApplication.run()方法&#xff0c;执行所有Spring Boot自动配置的Be…...

Git相关命令

SSH密钥文件 Github里面S设置SH公钥有两者选择方式 账号下的每个仓库都设置一个公钥&#xff0c;因为GitHub官方要求每个仓库的公钥都不能相同&#xff0c;所以每个账号都要搞一个密钥&#xff08;很麻烦&#xff09;给账号分配一个公钥&#xff0c;然后这个公钥就可以在这个…...

《HeadFirst设计模式(第二版)》第八章代码——模板方法模式

代码文件目录&#xff1a; CaffeineBeverage package Chapter8_TemplateMethodPattern;/*** Author 竹心* Date 2023/8/17**/public abstract class CaffeineBeverage {final void prepareRecipe(){boilWater();brew();pourInCup();//这里使用钩子customerWantsCondiments()来…...

RESTful API,以及如何使用它构建 web 应用程序

RESTful API是一种基于HTTP协议的API设计风格&#xff0c;它的核心思想是将资源作为 API 的核心&#xff0c;使用 HTTP 的 GET、POST、PUT、DELETE 等方法对这些资源进行操作&#xff0c;并通过 URL 来定位资源。 RESTful API的特点包括&#xff1a; 资源是 API 的核心使用 H…...

Git+Gitee使用分享

GitGitee快速入门 创建仓库 ​ ​ ​ 初始化本地仓库 验证本地git是否安装好 打开cmd窗口&#xff0c;输入git ​ 这样就OK。 Git 全局设置:(只需要设置一次) 这台电脑如果是第一次使用git&#xff0c;就需要这样初始化一下&#xff0c;这样才知道是谁提交到仓库了。 git confi…...

【3D激光SLAM】LOAM源代码解析--transformMaintenance.cpp

系列文章目录 【3D激光SLAM】LOAM源代码解析–scanRegistration.cpp 【3D激光SLAM】LOAM源代码解析–laserOdometry.cpp 【3D激光SLAM】LOAM源代码解析–laserMapping.cpp 【3D激光SLAM】LOAM源代码解析–transformMaintenance.cpp 写在前面 本系列文章将对LOAM源代码进行讲解…...

DiscuzQ 二开教程(7)——二次开发版本部署文档

DiscuzQ 二开教程&#xff08;7&#xff09;——二次开发版本部署文档 源码&#xff1a;Discuz-Q-V3: 本仓库为Discuz-Q V3.0.211111 版本的二次开发版本&#xff0c;是将DiscuzQ官方仓库进行合并代码&#xff08;All in One&#xff09;整理后的仓库&#xff0c;使用更方便。…...

u盘数据丢失但占内存如何恢复?不要着急,这里有拯救方案

U盘数据丢失但占内存如何恢复&#xff1f;数据丢失是一种让人非常头疼的问题&#xff0c;尤其是当我们的U盘数据丢失了&#xff0c;但内存仍然被占用时&#xff0c;更令人困惑和焦虑。然而&#xff0c;不要慌张&#xff01;在本文中&#xff0c;将为大家介绍一些有效的方法来恢…...

springboot日志文件名称为什么叫logback-spring.xml

如题&#xff0c;为什么springboot日志配置文件叫logback-spring.xml&#xff1f; 在整个项目中搜索 logback-spring.xml 并没有搜索到。 先看一下 org.springframework.boot.context.logging.LoggingApplicationListener#initialize protected void initialize(ConfigurableEn…...

Mysql 开窗函数(窗口函数)

文章目录 全部数据示例1&#xff08;说明&#xff09;开窗函数可以比groupby多查出条件列外的字段&#xff0c;开窗函数主要是为了跟聚合函数一起使用&#xff0c;达到分组统计效果&#xff0c;并且开窗函数的结果集基本都是跟总行数一样示例2示例3示例4错误示例1错误示例2错误…...

计算机视觉之图像特征提取

图像特征提取是计算机视觉中的重要任务&#xff0c;它有助于识别、分类、检测和跟踪对象。以下是一些常用的图像特征提取算法及其简介&#xff1a; 颜色直方图&#xff08;Color Histogram&#xff09;&#xff1a; 简介&#xff1a;颜色直方图表示图像中各种颜色的分布情况。通…...

【面试经典150题】移除元素·JavaScript版

题目来源 大致思路&#xff1a;遍历数组&#xff0c;如果遇到值为val的元素&#xff0c;使用数组最后一个元素替换它。详细过程&#xff1a; /*** param {number[]} nums* param {number} val* return {number}*/ var removeElement function(nums, val) {let i0,nnums.leng…...

Cesium 相机的三种放置方式

文章目录 Cesium 相机的三种放置方式第一种&#xff1a;setView 计算视角1. Cartesian3 方式2. Rectangle 方式 第二种&#xff1a;flyTo第三种&#xff1a;lookAt Cesium 相机的三种放置方式 Cesium 提供了三种方式对相机的位置进行摆放 第一种&#xff1a;setView 计算视角 …...

看了我这篇帖子,你还会觉得制作电子杂志很难吗?

如果你也像我一样笨手笨脚的不会设计排版制作杂志也没关系&#xff0c;用FLBOOK就能在线制作电子杂志&#xff0c;效果极好&#xff01; 工具&#xff1a;FLBOOK 步骤如下&#xff1a; 1.打开FLBOOK在线制作电子杂志平台 2.点击开始创作&#xff0c;有四个创建作品的方式&…...

SRE 与开发的自动化协同 -- 生产环境出现 bug 自动生成异常追踪

简介 生产环境 bug 的定义&#xff1a;RUM 应用和 APM 应用的 error_stack 信息被捕捉后成为 bug。 以 APM 新增错误巡检为例&#xff0c;当出现新错误时&#xff0c;在观测云控制台的「事件」模块下生成新的事件报告&#xff0c;捕捉为 bug。同时利用 Dataflux Func 创建异常…...

【简单认识Docker基本管理】

文章目录 一、Docker概述1、定义2.容器化流行的原因3.Docker和虚拟机的区别4.Docker核心概念 二、安装docker三、镜像管理1.搜索镜像2.下载&#xff08;拉取&#xff09;镜像3.查看已下载镜像4.查看镜像详细信息5.修改镜像标签6.删除镜像7.导出镜像文件和拉取本地镜像文件8.上传…...