QT基础篇(10)QT5网络与通信

QT5网络与通信是指在QT5开发环境中使用网络进行数据传输和通信的相关功能和技术。

QT5提供了一套完善的网络模块,包括了TCP、UDP、HTTP等协议的支持,可以方便地在QT应用程序中进行网络通信。通过QT5的网络模块,开发者可以实现客户端和服务器之间的数据传输、消息推送、远程控制等功能。

在QT5中,可以使用QTcpSocket类和QUdpSocket类来实现TCP和UDP协议的数据传输。QTcpSocket类提供了基于TCP协议的套接字接口,可以实现可靠的数据传输和连接管理;QUdpSocket类则提供了基于UDP协议的套接字接口,可以实现快速的数据传输和广播。

除了基本的TCP和UDP通信,QT5还提供了QNetworkAccessManager类和QNetworkRequest类来实现HTTP通信。QNetworkAccessManager类是QT5中的HTTP客户端类,可以实现HTTP请求和响应的处理;QNetworkRequest类用于表示HTTP请求的相关信息,如URL地址、请求头等。

此外,QT5还提供了一些其他的网络相关类和功能,如QTcpServer类用于实现TCP服务器端的功能、QSslSocket类用于实现安全的网络通信、QWebSocket类用于实现WebSocket协议的通信等。

总之,QT5网络与通信提供了一套简单易用、功能丰富的网络编程接口,使得开发者可以方便地在QT应用程序中实现各种网络通信功能。

1.获取本机网络信息

在QT5中,可以使用QNetworkInterface类来获取本机的网络信息。QNetworkInterface类提供了一组静态函数用于查询本机的网络接口信息,如IP地址、MAC地址等。

以下是一个示例代码,展示如何使用QNetworkInterface类获取本机网络信息:

#include <QtNetwork>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 获取本机的网络接口列表QList<QNetworkInterface> interfaceList = QNetworkInterface::allInterfaces();// 遍历网络接口列表foreach (QNetworkInterface interface, interfaceList) {// 输出网络接口的名称和硬件地址(MAC地址)qDebug() << "Interface name:" << interface.name();qDebug() << "Hardware address (MAC):" << interface.hardwareAddress();// 获取接口的IP地址列表QList<QNetworkAddressEntry> addressList = interface.addressEntries();foreach (QNetworkAddressEntry entry, addressList) {// 输出IP地址和子网掩码qDebug() << "IP address:" << entry.ip().toString();qDebug() << "Netmask:" << entry.netmask().toString();}qDebug() << "------------------------------------";}return a.exec();
}

上述代码使用QNetworkInterface::allInterfaces()函数获取本机的所有网络接口列表,然后通过遍历列表,获取每个网络接口的名称、硬件地址(MAC地址)、IP地址等信息,并进行输出展示。

注意,要使用QT的网络模块,需要在.pro文件中添加QT += network声明,以添加网络模块的依赖。

运行上述代码,即可获取到本机的网络信息,并进行输出展示。

2.基于UDP的网络广播程序
2.1 UDP工作原理

UDP(User Datagram Protocol)是一种无连接的传输层协议,它在网络通信中提供了一种简单的、不可靠的数据传输方式。与TCP相比,UDP不提供可靠的传输和重发机制,也没有流量控制和拥塞控制。UDP主要用于那些对实时性要求较高,对数据丢失不敏感的应用场景,如音视频传输、在线游戏等。

UDP的工作原理如下:

  1. 建立UDP套接字:在数据传输之前,发送方和接收方需要分别创建UDP套接字(socket)。套接字是网络通信的端点,用于发送和接收数据。

  2. 发送数据报文:发送方将待发送的数据封装成一个数据报,并通过UDP套接字发送出去。数据报由目标IP地址和端口号标识。

  3. 数据报文传输:UDP将数据报直接传输给目标主机,不进行可靠性保证和流量控制。数据报可能会被网络中的路由器丢失、延迟或重排序。

  4. 数据报文接收:接收方的UDP套接字接收到数据报后,将其解析为原始数据,并提供给应用程序使用。

UDP的特点和适用场景:

  • 无连接:UDP在通信前不需要进行握手和建立连接,因此可以更快地发送数据。
  • 不可靠:数据报可能会丢失、重复、乱序传输,因为UDP不提供重发和确认机制。
  • 尽力而为:UDP尽最大努力交付数据,但不能保证数据的可靠性和按序性。
  • 适用于实时性要求高、数据丢失不敏感的应用场景,如音视频传输、实时游戏等。

总结:UDP是一种简单、高效的传输协议,适用于实时性要求较高、对数据丢失不敏感的应用场景。它不提供可靠性保证和流量控制,但传输速度快,延迟低。

2.2  UDP编程模型

UDP编程模型是一种用于在应用程序中实现UDP通信的方式。UDP编程模型主要包括以下几个步骤:

  1. 创建UDP套接字:在应用程序中创建一个UDP套接字,套接字是进行网络通信的端点,用于发送和接收数据。

  2. 绑定套接字:将套接字绑定到一个特定的本地IP地址和端口号上。这样,套接字就可以接收来自该IP地址和端口号的数据。

  3. 发送数据:通过UDP套接字发送数据报文。发送时,需要指定目标IP地址和端口号。

  4. 接收数据:通过UDP套接字接收数据报文。可以使用非阻塞模式或阻塞模式进行接收。

  5. 处理接收的数据:应用程序处理接收到的数据报文,解析其中的数据并进行相关的处理。

  6. 关闭套接字:完成UDP通信后,应用程序需要关闭套接字释放资源。

在实际的UDP编程中,可以使用不同的编程语言和框架来实现UDP通信。例如,使用C语言可以使用socket API来创建和管理UDP套接字,使用Python可以使用socket模块来进行UDP编程,使用Qt框架可以使用QUdpSocket类来实现UDP通信等。

总结:UDP编程模型包括创建UDP套接字、绑定套接字、发送和接收数据以及处理数据的过程。通过使用不同的编程语言和框架,可以实现UDP通信并进行相应的数据处理。

2.3 UDP服务器编程

在QT5中,可以使用QUdpSocket类来实现UDP服务器端的编程。以下是一个基本的QT5 UDP服务器端编程的示例:

#include <QtNetwork>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 创建一个QUdpSocket对象QUdpSocket udpSocket;// 绑定服务器的IP地址和端口号udpSocket.bind(QHostAddress::AnyIPv4, 1234);// 当有数据到达时触发readyRead()函数QObject::connect(&udpSocket, &QUdpSocket::readyRead, [&](){while (udpSocket.hasPendingDatagrams()) {// 读取接收到的数据报文QByteArray datagram;datagram.resize(udpSocket.pendingDatagramSize());udpSocket.readDatagram(datagram.data(), datagram.size());// 处理接收到的数据,这里简单打印出数据内容qDebug() << "Received data: " << datagram;}});return a.exec();
}

在上面的代码中,首先创建一个QUdpSocket对象udpSocket,然后使用bind()函数将其绑定到服务器端的IP地址和端口号上(这里使用了任意IPv4地址和端口号1234)。接下来,使用QObject的connect()函数将udpSocket的readyRead信号连接到一个lambda函数,该函数会在有数据到达时被触发。在lambda函数中,通过udpSocket的pendingDatagramSize()函数获取待处理数据报文的大小,并使用readDatagram()函数读取数据报文的内容。最后,可以根据业务需求进行对接收数据的处理。

请注意,以上示例仅为演示UDP服务器端的基本逻辑,实际的服务器端编程可能还需要处理各种异常情况,进行错误处理,以及向客户端发送响应等。

2.4 UDP客户端编程

在QT5中,可以使用QUdpSocket类来实现UDP客户端的编程。以下是一个基本的QT5 UDP客户端编程的示例:

#include <QtNetwork>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 创建一个QUdpSocket对象QUdpSocket udpSocket;// 发送数据报文到服务器端QByteArray datagram = "Hello, server!";udpSocket.writeDatagram(datagram, QHostAddress("127.0.0.1"), 1234);// 当有数据到达时触发readyRead()函数QObject::connect(&udpSocket, &QUdpSocket::readyRead, [&](){while (udpSocket.hasPendingDatagrams()) {// 读取接收到的数据报文QByteArray datagram;datagram.resize(udpSocket.pendingDatagramSize());udpSocket.readDatagram(datagram.data(), datagram.size());// 处理接收到的数据,这里简单打印出数据内容qDebug() << "Received data: " << datagram;}});return a.exec();
}

在上面的代码中,首先创建一个QUdpSocket对象udpSocket。然后,使用writeDatagram()函数向服务器端发送数据报文,其中datagram是要发送的数据,QHostAddress("127.0.0.1")是服务器的IP地址,1234是服务器的端口号。接下来,使用QObject的connect()函数将udpSocket的readyRead信号连接到一个lambda函数,该函数会在有数据到达时被触发。在lambda函数中,通过udpSocket的pendingDatagramSize()函数获取待处理数据报文的大小,并使用readDatagram()函数读取数据报文的内容。最后,可以根据业务需求进行对接收数据的处理。

请注意,以上示例仅为演示UDP客户端的基本逻辑,实际的客户端编程可能还需要处理各种异常情况,进行错误处理,以及定时发送数据等。

3.基于TCP的网络聊天室程序
3.1 TCP工作原理

TCP(Transmission Control Protocol)是一种可靠的、面向连接的传输层协议,用于在网络上传输数据。它提供了以下主要功能:

  1. 连接建立:在通信双方之间建立一个可靠的连接,形成一个数据传输通道。

  2. 可靠性:通过使用序列号、确认应答、重传机制等,确保数据的可靠传输。如果数据丢失或损坏,TCP会要求对方重新发送。

  3. 拥塞控制:通过动态调整发送速率,避免网络拥塞,保持良好的网络性能。

  4. 面向字节流:TCP把数据看作是一连串的无结构的字节流,没有明确的数据报文边界。TCP会保持字节的顺序,并对字节进行分割和重组。

  5. 流量控制:通过滑动窗口机制,控制发送方的发送速率,使接收方能够及时处理接收到的数据。

  6. 超时重传:如果一段时间内没有收到对方的确认应答,TCP会重新发送之前发送的数据。

TCP的工作原理如下:

  1. 三次握手建立连接:

    • 客户端发送一个SYN(同步)报文给服务端,请求建立连接。
    • 服务端接收到SYN报文后,回复一个SYN+ACK(同步+确认)报文,表示同意建立连接。
    • 客户端收到服务端的SYN+ACK报文后,再回复一个ACK(确认)报文,建立连接。
  2. 数据传输:

    • 连接建立后,可以进行数据的传输。客户端通过发送数据报文给服务端,服务端接收到数据后进行处理。
    • 数据报文按序列号分割成报文段,并发送给接收方。
    • 接收方收到报文段后,根据序列号进行排序和重组,然后交给应用层进行处理。
  3. 连接释放:

    • 当数据传输结束后,或者发生异常情况时,需要关闭连接。
    • 一方发送一个FIN(结束)报文给对方,表示要关闭连接。
    • 接收方收到FIN报文后,回复一个ACK报文进行确认。
    • 接收方也可以发送一个FIN报文给发送方,表示同意关闭连接。
    • 最后,发送方收到ACK报文后,连接关闭。

通过以上的握手和释放过程,TCP协议可以确保可靠的数据传输,并提供了流量控制和拥塞控制机制,使得数据在网络上能够高效、可靠地传输。

3.2 TCP编程模型

TCP编程模型是一种基于TCP协议的网络编程模型,用于实现网络应用程序的通信。它包括以下几个步骤:

  1. 创建Socket:在客户端和服务器端分别创建一个Socket对象,用于建立连接并进行数据的传输。客户端需要指定服务器的IP地址和端口号,而服务器只需指定一个监听的端口号。

  2. 建立连接:客户端通过调用Socket对象的connect()方法,向指定的服务器地址和端口号发起连接请求。如果连接成功,客户端和服务器端都会创建一个TCP连接。

  3. 数据发送和接收:连接建立后,客户端和服务器端可以通过Socket对象的send()和recv()方法来发送和接收数据。客户端可以将需要发送的数据通过send()方法发送给服务器端,而服务器则通过recv()方法接收客户端发送的数据。

  4. 关闭连接:当通信结束后,客户端和服务器端均需要调用Socket对象的close()方法来关闭连接。

在TCP编程模型中,客户端和服务器端的代码逻辑有所不同:

客户端代码逻辑:

  1. 创建Socket对象;
  2. 连接服务器;
  3. 发送数据;
  4. 接收数据;
  5. 关闭连接。

服务器端代码逻辑:

  1. 创建Socket对象;
  2. 绑定监听端口;
  3. 进入监听状态,等待客户端连接;
  4. 接收连接请求;
  5. 接收数据;
  6. 发送数据;
  7. 关闭连接。

需要注意的是,TCP编程模型是基于阻塞IO的,即当一个操作被执行时,程序会一直等待该操作完成后再继续执行下一步操作。如果需要实现非阻塞IO,可以使用多线程或异步IO等方式来实现。

3.3 TCP服务器编程

在QT5中编写TCP服务器程序的步骤如下:

  1. 导入所需的QT相关模块:
#include <QTcpServer>
#include <QTcpSocket>

  1. 创建QTcpServer对象和QTcpSocket对象:
QTcpServer *server = new QTcpServer;
QTcpSocket *socket;

  1. 监听客户端连接请求并处理:
bool success = server->listen(QHostAddress::Any, 1234); // 监听任意地址的1234端口
if(!success) {// 监听失败的处理逻辑
}// 当有客户端连接请求时,执行连接事件的处理函数
connect(server, &QTcpServer::newConnection, [=]() {socket = server->nextPendingConnection(); // 接受连接请求并返回一个新的socket对象// 连接建立成功的处理逻辑// 处理接收到的数据connect(socket, &QTcpSocket::readyRead, [=]() {QByteArray data = socket->readAll(); // 读取接收到的数据// 处理接收到的数据的逻辑});// 处理连接断开connect(socket, &QTcpSocket::disconnected, [=]() {socket->deleteLater(); // 删除socket对象});
});

  1. 在需要发送数据时,使用QTcpSocket对象来发送数据:
socket->write("Hello, client!");// 发送数据

  1. 关闭服务器:
server->close();

注:以上代码只是简单的示例,实际应用中需根据具体情况进行修改和完善。

3.4 TCP客户端编程

在QT5中编写TCP客户端程序的步骤如下:

  1. 导入所需的QT相关模块:
#include <QTcpSocket>

  1. 创建QTcpSocket对象:
QTcpSocket *socket = new QTcpSocket;

  1. 连接到服务器:
socket->connectToHost("服务器IP", 1234); // 连接到服务器的IP和端口号
if(socket->waitForConnected()) {// 连接成功的处理逻辑
} else {// 连接失败的处理逻辑
}

  1. 处理接收到的数据:
connect(socket, &QTcpSocket::readyRead, [=]() {QByteArray data = socket->readAll(); // 读取接收到的数据// 处理接收到的数据的逻辑
});

  1. 在需要发送数据时,使用QTcpSocket对象来发送数据:
socket->write("Hello, server!"); // 发送数据

  1. 关闭连接:
socket->close();

注:以上代码只是简单的示例,实际应用中需根据具体情况进行修改和完善。

4.QT网络应用开发初步
4.1 简单网页浏览器

在QT5中编写一个简单的网页浏览器,需要使用QT的QWebEngineView类来显示网页内容。以下是一个基本的示例:

  1. 导入所需的QT相关模块:
#include <QApplication>
#include <QWebEngineView>

  1. 创建一个QWebEngineView对象并设置其大小和标题:
QWebEngineView *view = new QWebEngineView;
view->resize(800, 600); // 设置窗口大小
view->setWindowTitle("Simple Web Browser"); // 设置窗口标题

  1. 加载网页:
view->load(QUrl("http://www.example.com")); // 加载指定网页

  1. 显示窗口:
view->show(); // 显示窗口

  1. 运行应用程序:
return QApplication::exec(); // 运行QT应用程序的事件循环

完整的示例代码如下:

#include <QApplication>
#include <QWebEngineView>int main(int argc, char *argv[])
{QApplication a(argc, argv);QWebEngineView *view = new QWebEngineView;view->resize(800, 600);view->setWindowTitle("Simple Web Browser");view->load(QUrl("http://www.example.com"));view->show();return QApplication::exec();
}

可以根据需要修改网页的URL和窗口大小等参数。编译运行该示例代码,即可打开一个简单的网页浏览器窗口,并加载指定的网页。

4.2 文件下载实例

在QT5中实现文件下载可以使用QNetworkAccessManagerQNetworkReply类。以下是一个简单的示例:

#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QFile>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);QString url = "https://www.example.com/file.txt"; // 下载文件的URLQString savePath = "/path/to/save/file.txt"; // 保存文件的路径QNetworkAccessManager manager;QNetworkReply *reply = manager.get(QNetworkRequest(QUrl(url)));// 连接下载完成的信号QObject::connect(reply, &QNetworkReply::finished, [&a, reply, savePath]() {if (reply->error() == QNetworkReply::NoError) {QFile file(savePath);if (file.open(QIODevice::WriteOnly)) {file.write(reply->readAll());file.close();qDebug() << "File downloaded successfully.";} else {qDebug() << "Failed to open file for writing.";}} else {qDebug() << "Download failed:" << reply->errorString();}reply->deleteLater();a.quit();});return a.exec();
}

在上面的示例中,我们创建了一个QNetworkAccessManager对象,并使用get()函数发起一个GET请求来下载文件。然后,我们连接QNetworkReply对象的finished()信号,当下载完成时,会触发该信号,我们在该信号的槽函数中将文件保存到指定的路径。如果下载过程中出错,我们会输出错误信息。最后,我们调用a.quit()来退出应用程序。

请注意将https://www.example.com/file.txt替换为实际的文件下载链接,并将/path/to/save/file.txt替换为文件保存的实际路径。

编译运行该示例代码,即可实现文件下载功能。

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

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

相关文章

npm install 太慢?解决方法

在使用npm进行包管理时&#xff0c;有时会遇到安装速度缓慢的问题。这可能是由于网络原因或npm官方镜像服务器的繁忙导致的。下面介绍几种常见的解决方法&#xff1a; 使用淘宝镜像 淘宝镜像是一个提供npm包镜像的国内源&#xff0c;其速度较快且稳定。您可以通过以下命令将np…

《WebKit 技术内幕》之四(1): 资源加载和网络栈

第四章 资源加载和网络栈 使用网络栈来下载网页和网页资源是渲染引擎工作的第一步 1.WebKit 资源加载机制 1.1 资源 网页本身就是一种资源、网页还需要依赖很多其他的资源(图片、视频) &#xff08;1&#xff09;HTML 支持的资源主要包括以下几种类型&#xff1a; HTML 页…

Elasticsearch 数据类型相关总结:快速参考指南【记录】

在Elasticsearch中&#xff0c;有多种数据类型可用于定义字段。 在开始了解数据类型之前&#xff0c;首先要知道&#xff0c;在Elasticsearch中&#xff0c;分词处理主要针对文本字段&#xff0c;而对于其他类型字段&#xff08;如数值、日期、布尔等&#xff09;&#xff0c;通…

周五的胡思乱想

众所周知 csdn 在程序员的心目中是比较逊色的, 因为博客水平的参差不齐, 大部分人也都是用来作为自己的笔记方便未来复制。这样就导致这里的文章都是点到为止&#xff0c;没有去深究问题的根本原因&#xff0c;大家也都是复制一下解决方案就关闭的页面。或许这就是 csdn 的价值…

免费chartGPT网站汇总--

https://s.suolj.com - &#xff08;支持文心、科大讯飞、智谱等国内大语言模型&#xff0c;Midjourney绘画、语音对讲、聊天插件&#xff09;国内可以直连&#xff0c;响应速度很快 很稳定 https://seboai.github.io - 国内可以直连&#xff0c;响应速度很快 很稳定 http://gp…

智能开发助手——华为云CodeArts Snap,揭开智能研发新篇章

AIGC浪潮席卷全球&#xff0c;大模型技术应用到软件开发领域&#xff0c;正在颠覆传统的软件工程。华为云CodeArts Snap是一款基于大模型技术打造的智能开发助手&#xff0c;旨在提高开发人员的生产力和代码质量&#xff0c;为开发者带来全新的编程方式和体验。 ▶华为云智能开…

视频直播新时代,低延时直播交互,Web,Android,WebRtc推流拉流测试

直播现在已经深入了生活&#xff0c;学习&#xff0c;工作和娱乐方方面面&#xff0c;由于前些年的技术所限&#xff0c;传统rtmp,flv,m3u8 技术让直播快速启动项目产品&#xff0c;但也有很多不足&#xff0c;特别的交互式直播&#xff0c;一直是其中的痛点&#xff0c;延时较…

《剑指 Offer》专项突破版 - 面试题 16 : 不含重复字符的最长子字符串(C++ 实现)

题目链接&#xff1a;LCR 016. 无重复字符的最长子串 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 输入一个字符串&#xff0c;求该字符串中不含重复字符的最长子字符串的长度。例如&#xff0c;输入字符串 "babcca"&#xff0c;其最长的不含重复字符…

Oracle学习笔记——基础一起学 14

第十四天 DECODE的简单例子 用case实现 --DECODE的简单例子 --用case实现 select id,name, case sex when 1 then 男 when 2 then 女 end 性别 from student; --DECODE取出一行内两列中的较大值 --先建表 create table sales(month char(2),sales_tv number,sales_…

C#MQTT编程07--MQTT服务器和客户端(wpf版)

1、前言 上篇完成了winform版的mqtt服务器和客户端&#xff0c;实现了订阅和发布&#xff0c;效果666&#xff0c;长这样 这节要做的wpf版&#xff0c;长这样&#xff0c;效果也是帅BBBB帅&#xff0c;wpf技术是cs程序软件的福音。 wpf的基础知识和案例项目可以看我的另一个专…

Spring 如何解决循环依赖?

Spring解决循环依赖的主要方式是通过使用三级缓存&#xff08;three-level cache&#xff09;来管理Bean的创建过程。Spring容器在创建Bean时&#xff0c;会将Bean的创建状态存储在三级缓存中&#xff0c;以解决循环依赖的问题。 以下是Spring解决循环依赖的基本原理&#xff…

Parade Series - RTSP - Web

Cron Startup Scripts └─ lt-init.cmd├─ lt-server.cmd│ └─ lt-rtsp-proxy-server.cmd│ └─ lt-rtsp-proxy-agent.cmd└─ lt-push.cmd└─ lt-rtsp-cam-daemon.cmd└─ lt-rtsp-cam-worker.cmdlt-init.cmd :: :: PLEASE DO NOT EDIT THIS FILE :: ECHO OFF…

Qt —— 编译Qt5版本QFTP库,并实现连接服务、获取列表、上传、下载、删除文件等操作(附源码、附基于Qt5编译好的QFTP库)

示例效果1 示例效果2 介绍 QFTP是Qt4的库,Qt5改用了QNetworkAccessManager来代替。但是Qt5提供的QNetworkAccessManager仅支持FTP的上传和下载,所以只能将QFTP库编译为Qt5的库来进行调用。 QFTP在Github的下载地址:https://github.com/qt/qtftp 客户端源码生成的release结果…

安全 漏洞扫描 OSSIM

安全 漏洞扫描OSSIM OSSIM &#xff08;4&#xff09;硬件选择&#xff0c;可以采用品服务器&#xff0c;对于中小企业也可以根据自己需求&#xff0c;以OSSIM 4.8系统为例&#xff0c;目前系统对多核性能支持的比较好&#xff0c;推荐采用至强E系列处理器&#xff0c;OSSIM在…

IDEA项目启动报错之Command too long

使用IDEA最新的版本2023-3月份社区版本&#xff0c;启动之前没问题的项目突然报错如下&#xff1a; Error running VipServiceApplication: Error running // VipServiceApplication.Command line is too long. Shorten the command line via // JAR manifest or via a // clas…

开发安全之:Log Forging

Overview error_log($content . "\r\n", 3, $this->logFile);&#xff0c;该代码将未经验证的用户输入写入日志。攻击者可以利用这一行为来伪造日志条目或将恶意内容注入日志。 Details 在以下情况下会发生 Log Forging 的漏洞&#xff1a; 1. 数据从一个不可…

运放【之噪声】

电流噪声和电压噪声 我们一般评估噪声&#xff0c;还看对输出端噪声电压的贡献&#xff0c;因为电流乘以电阻等于电压&#xff0c;因此&#xff0c;最终的噪声大小还跟电路中电阻的取值有很大关系。显然&#xff0c;电阻越大&#xff0c;那么噪声电压就越大。反之电阻越小&…

设计模式——建造者模式(Builder Pattern)

概述 建造者模式是较为复杂的创建型模式&#xff0c;它将客户端与包含多个组成部分&#xff08;或部件&#xff09;的复杂对象的创建过程分离&#xff0c;客户端无须知道复杂对象的内部组成部分与装配方式&#xff0c;只需要知道所需建造者的类型即可。它关注如何一步一步创建一…

09 STM32 - PWM

9.1 PWM简介 脉冲宽度调制(Pulse Width Modulation,简称PWM)&#xff0c;是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点&#xff0c;就是对脉冲宽度的控制。 9.2 PWM波原理 如下图所示&#xff0c;使用定时器定时&#xff0c;从0开始&#x…

Ubuntu系统Git的安装配置及使用笔记(更新中)

Ubuntu下Git的下载及配置 (1)、下载git 打开终端命令窗口,输入&#xff1a;sudo apt-get install git 提示&#xff1a;sudo命令是用来以其他身份来执行命令&#xff0c;预设的身份为root,使用sudo时必须先输入密码 (2)、可以使用命令git --version查看git的版本号 (3)、设置…