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

ESP32(1)基于ESP32的lwIP了解

ESP32-S3 是一款集成了 Wi-Fi 和蓝牙功能的微控制器,而 lwIP(轻量级 IP)是一个为嵌入式系统设计的开源 TCP/IP 协议栈。通过使用 lwIP 库, ESP32-S3 可以实现与外部网络的通信,包括发送和接收数据包、处理网络连接等。因此, ESP32-S3 是基于 lwIP 来实现网络功能的。

TCP/IP 协议栈

TCP/IP 协议栈是一系列网络协议的总和,构成网络通信的核心骨架,定义了电子设备如何连入因特网以及数据如何在它们之间进行传输。该协议采用 4 层结构,分别是应用层、传输层、网络层和网络接口层, 每一层都使用下一层提供的协议来完成自己的需求。大部分时间都在应用层工作,下层的事情不用操心。此外,网络协议体系本身很复杂庞大,入门门槛高,因此很难搞清楚 TCP/IP 的工作原理。如果读者想深入了解 TCP/IP 协议栈的工作原理,建议阅读《计算机网络书籍》。

TCP/IP 协议栈架构

TCP/IP 协议栈是一个分层结构的模型,每一层负责不同的网络功能。整个协议栈可以被分为四层,从上到下分别是:应用层、传输层、网络层和网络接口层。

1.应用层:这是最顶层,负责处理特定的应用程序细节。在这一层,用户的数据被处理和解释。一些常见的应用层协议包括 HTTP、 FTP、 SMTP 和 DNS 等。

2.传输层:这一层负责数据包的分割、打包以及传输控制,确保数据能够可靠、有序地到达目的地。主要的传输层协议有 TCP 和 UDP。

3.网络层:负责确定数据包的路径从源到目的地。这一层的主要协议是 IP(InternetProtocol),它负责在主机之间发送和接收数据包。

4.网络接口层:这是最底层,负责将数据转换为可以在物理媒介上发送的信号。这一层的协议涉及到如何将数据帧封装在数据链路层,以便在网络上进行传输。

每一层都使用下一层提供的服务,同时对上一层提供服务。这种分层结构使得协议栈更加灵活,易于扩展和维护。不同层次上的协议一起工作,协调数据在计算机网络中的传输,使得不同的计算机能够相互通信。需要注意的是, TCP/IP 协议栈和传统的 OSI 模型并不完全对应。 TCP/IP 协议栈是一个简化的模型,强调了实际的协议实现和因特网的实际运作方式。相比之下, OSI 模型更加全面和理想化,它提供了一个框架来描述不同系统之间的交互方式。下图是 IOS 协议栈与 TCP/IP 协议栈分层架构的对比图。

ISO/OSI 分层模型也是一个分层结构,包括七个层次,从上到下分别是:应用层、表示层、会话层、传输层、网络层、数据链路层和物理层。虽然 ISO/OSI 模型为不同的系统之间的通信提供了一个理论框架,但 TCP/IP 协议栈更侧重于实际的协议实现和因特网的实际运作方式。注意:网络技术的发展并不是遵循严格的 ISO/OSI 分层概念。实际上现在的互联网使用的是TCP/IP 体系结构,但某些应用程序可以直接使用 IP层,或甚至直接使用最下面的网络接口层。

无论哪种表示方法, TCP/IP 模型各个层次都分别对应于不同的协议。 TCP/IP 协议栈负责确保网络设备之间能够通信。它是一组规则,规定了信息如何在网络中传输。其中,这些协议都分布在应用层,传输层和网络层,网络接口层是由硬件来实现。如 Windows 操作系统包含了CBISC 协议栈,该协议栈就是实现了 TCP/IP 协议栈的应用层,传输层和网络层的功能,网络接口层由网卡实现,所以 CBISC 协议栈和网卡构建了网络通信的核心骨架。因此,无论哪一款以太网产品,都必须符合 TCP/IP 体系结构,才能实现网络通信。注意:路由器和交换机等相关网络设备只实现网络层和网络接口层的功能。

TCP/IP 协议栈的封包和拆包

TCP/IP 协议栈的封包和拆包是指在网络通信中,将数据按照一定的协议和格式进行封装和解析的过程。在 TCP/IP 协议栈中,数据封装是指在发送端将数据按照协议规定的格式进行打包,以便在网络中进行传输。在应用层的数据被封装后,会经过传输层、网络层和网络接口层的处理,最终转换成可以在物理网络上传输的帧格式。数据封装的过程涉及到对数据的分段、压缩、加密等操作,以确保数据能够可靠、安全地传输到目的地,下图描述的是封包处理流程。

数据拆包是指接收端收到数据后,按照协议规定的格式对数据进行解析和处理,还原出原始的数据。在接收到数据后,接收端会按照协议规定的层次从下往上逐层处理数据,最终将应用层的数据还原出来。数据拆包的过程涉及到对数据的重组、解压缩、解密等操作,以确保数据能够被正确地解析和处理,下图描述的是拆包处理流程。

需要注意的是, TCP/IP 协议栈的封包和拆包过程涉及到多个层次和协议的处理,需要按照协议规定的格式和顺序进行操作。在实际应用中,需要根据具体的情况选择合适的协议和格式来满足不同的需求。同时,为了保证数据的安全和可靠性,还需要采取相应的加密、压缩等措施,以避免数据被篡改或损坏。

lwIP 简介

lwIP,全称为 Lightweight IP协议,是一种专为嵌入式系统设计的轻量级 TCP/IP协议栈。它可以在无操作系统或带操作系统环境下运行,支持多线程或无线程,适用于 8 位和 32 位微处理器,同时兼容大端和小端系统。它的设计核心理念在于保持 TCP/IP 协议的主要功能同时尽量减少对 RAM 的占用。这意味着,尽管它的体积小巧, 但它能够实现完整的 TCP/IP 通信功能。通常, lwIP 只需十几 KB 的 RAM 和大约 40K 的 ROM 即可运行,使其成为资源受限的嵌入式系统的理想选择。 lwIP 的灵活性使其既可以在无操作系统环境下工作,也可以与各种操作系统配合使用。这为开发者提供了更大的自由度,可以根据具体的应用需求和硬件配置进行优化。无论是在云台接入、无线网关、远程模块还是工控控制器等场景中, lwIP 都能提供强大的网络支持。

lwIP 特性参数

lwIP 的各项特性,如下表所示:

lwIP 与 TCP/IP 体系结构的对应关系

从上图可以清晰地看到, lwIP 软件库主要实现了 TCP/IP 体系结构中的三个层次:应用层、传输层和网络层。这些层次共同处理和传输数据包,确保了数据在网络中的可靠传输。然而,网络接口层作为 TCP/IP 协议栈的最底层,其功能并无法通过软件方式完全实现。这一层的主要任务是将数据包转换为光电模拟信号,以便能够在物理媒介上传输。这个过程涉及到与硬件的直接交互,包括数据的调制解调、信号的转换等,这些都是软件难以模拟或实现的。因此,虽然 lwIP 软件库没有实现网络接口层的功能,但通过与底层硬件的紧密配合,它仍然能够提供完整且高效的 TCP/IP 通信功能。这也使得 lwIP 成为一个适用于资源受限的嵌入式系统的理想选择。在开发过程中,开发者需要根据具体的硬件平台和需求进行相应的配置和优化,以确保lwIP 能够与硬件完美配合,发挥出最佳的性能。

WiFi MAC 内核简介

ESP32-S3 完全遵循 802.11b/g/n Wi-Fi MAC 协议栈,支持分布式控制功能(DCF)下的基本服务集(BSS) STA 和 SoftAP 操作。支持通过最小化主机交互来优化有效工作时长,以实现功耗管理。 ESP32-S3 Wi-Fi MAC 支持 4 个虚拟 Wi-Fi 接口,同时支持基础结构型网络、 SoftAP 模式和 Station+SoftAP 混杂模式。它还具备 RTS 保护、 CTS 保护、立即块确认、分片和重组、TX/RX A-MPDU和TX/RX A-MSDU等高级功能。此外, ESP32-S3还支持无线多媒体、 GCMP、CCMP、 TKIP、 WAPI 等安全协议,并提供自动 Beacon 监测和 802.11mc FTM 支持。
关于 ESP32 的 WiFi MAC 内核,官方没有提供更多学习资料。读者只需了解它扮演 TCP/IP协议的网络接口层角色即可。使用一张示意图来介绍 WiFi 通讯示意图,如下图所示。

从上图可以看出, ESP32-S3 芯片内置 WiFi MAC 内核。当我们发送数据到网络时,数据首先被转化为无线信号,然后发送到该设备连接的 WiFi 路由器中。接着,路由器通过网线将数据传输到目标主机,从而完成数据传输操作。以下是作者对于无线网络传输的描述。

1.数据转化为无线信号:当 ESP32-S3 想要发送数据到网络时,它首先会将数据封装到一个无线传输帧中。这一过程涉及到将数据转化为可以在无线介质上传输的格式。

2.发送到 WiFi 路由器:封装后的无线信号然后被发送到 ESP32-S3 连接的 WiFi 路由器。WiFi 路由器充当一个中间设备,负责将无线信号转换为有线网络信号(如果目标主机是通过有线网络连接的)或直接转发无线信号(如果目标主机也是通过 WiFi 连接的)。

3.路由器传输数据: WiFi 路由器接收到无线信号后,会进一步处理它。如果目标主机是通过有线网络连接的,路由器会将无线信号转换为有线网络信号,并通过网线将其传输到目标主机。如果目标主机也是通过 WiFi 连接的,路由器会直接转发无线信号到目标主机。

4.完成数据传输:最终,目标主机接收到路由器发送的有线网络信号或无线信号,并将其解析为原始数据。这样,整个数据传输过程就完成了。

在整个过程中, ESP32-S3 的 WiFi MAC 内核起着核心的作用,它负责管理无线连接、封装和解封装数据以及与 WiFi 路由器进行通信。

lwIP Socket 编程接口

lwIP 作者为了方便开发者将其他平台上的网络应用程序移植到 lwIP 上,并让更多开发者快速上手 lwIP,作者设计了三种应用程序编程接口: RAW 编程接口、 NETCONN 编程接口和Socket 编程接口。然而,由于 RAW 编程接口只能在无操作系统环境下运行,因此对于内嵌FreeRTOS 操作系统的 ESP32 来说,无法使用这个编程接口。尽管 Socket 编程接口是由NETCONN 编程接口封装而成,但是该接口非常简易的实现网络连接(作者推荐使用此接口)。需要注意的是,由于受到嵌入式处理器资源和性能的限制,部分 Socket 接口并未在 lwIP 中完全实现。因此,为了实现网络连接,推荐使用 Socket API。下面作者简单介绍一下 lwIP Socket 编程接口常用的 API 函数。这些 API 函数如下所示。

socket 函数

该函数的原型,如下源码所示:

#define socket(domain,type,protocol) lwip_socket(domain,type,protocol)

向内核申请一个套接字,本质上该函数调用了函数 lwip_socket,该函数的参数如下表所示:

bind 函数

该函数的原型,如下源码所示:

#define bind(s,name,namelen) lwip_bind(s,name,namelen)
int bind(int s, const struct sockaddr *name, socklen_t namelen)

该函数与 netconn_bind 函数一样,用于服务器端绑定套接字与网卡信息,本质上就是对函数 netconn_bind 再一次封装,从上述源码可以知道参数 name 指向一个 sockaddr 结构体,它包含了本地 IP 地址和端口号等信息;参数 namelen 指出结构体的长度。结构体 sockaddr 定义如下源码所示:

struct sockaddr {u8_t sa_len; /* 长度 */sa_family_t sa_family; /* 协议簇 */char sa_data[14]; /* 连续的 14 字节信息 */
};struct sockaddr_in {u8_t sin_len; /* 长度 */u8_t sin_family; /* 协议簇 */u16_t sin_port; /* 端口号 */struct in_addr sin_addr; /* IP 地址 */char sin_zero[8];
};

可以看出, lwIP 作者定义了两个结构体,结构体 sockaddr 中的 sa_family 指向该套接字所使用的协议簇,本地IP地址和端口号等信息在sa_data数组里面定义,这里暂未用到。由于sa_data以连续空间的方式存在,所以用户要填写其中的 IP 字段和端口 port 字段,这样会比较麻烦,因此 lwIP 定义了另一个结构体 sockaddr_in,它与 sockaddr 结构对等,只是从中抽出 IP 地址和端口号 port,方便于用于的编程操作。

connect 函数

该函数与 netconn 接口的 netconn_connect 函数作用是一样的,因此它是被 netconn_connect函数封装了,该函数的作用是将 Socket 与远程 IP 地址和端口号绑定,如果开发板作为客户端,通常使用这个函数来绑定服务器的 IP 地址和端口号,对于 TCP 连接,调用这个函数会使客户端与服务器之间发生连接握手过程,并建立稳定的连接;如果是 UDP 连接,该函数调用不会有任何数据包被发送,只是在连接结构中记录下服务器的地址信息。当调用成功时,函数返回 0;否则返回-1。该函数的原型如下源码所示:

#define connect(s,name,namelen) lwip_connect(s,name,namelen)
int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen);

listen 函数

该函数和 netconn 的函数 netconn_listen 作用一样,它是由函数 netconn_listen 封装得来的,内核同时接收到多个连接请求时,需要对这些请求进行排队处理,参数 backlog 指明了该套接字
上连接请求队列的最大长度。当调用成功时,函数返回 0;否则返回-1。该函数的原型如下源码所示:

#define listen(s,backlog) lwip_listen(s,backlog)
int lwip_listen(int s, int backlog);

注意: 该函数作用于 TCP 服务器程序。

accept 函数

该函数与 netconn_accept作用是一样的,当接收到新连接后,连接另一端(客户端)的地址信息会被填入到地址结构 addr 中,而对应地址信息的长度被记录到 addrlen 中。函数返回新连接的套接字描述符,若调用失败,函数返回-1。该函数的原型如下源码所示:

#define accept(s,addr,addrlen) lwip_accept(s,addr,addrlen)
int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);

注意: 该函数作用于 TCP 服务器程序。

send()/sendto()函数

该函数是被 netconn_send 封装的,其作用是向另一端发送 UDP 报文,这两个函数的原型如下源码所示:

#define send(s,dataptr,size,flags) lwip_send(s,dataptr,size,flags)
#define sendto(s,dataptr,size,flags,to,tolen) lwip_sendto(s,dataptr,size,flags,to,tolen)
ssize_t lwip_send(int s, const void *dataptr, size_t size, int flags);
ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen);

可以看出,函数 sendto 比函数 send 多了两个参数,该函数如下表所示:

参数描述
sSocket 接口
dataptr发送数据的起始地址
size长度
flags数据发送时的特殊处理,例如带外数据、紧急数据等,通常设置为 0
to(sendto())目的地址信息
tolen(sendto())信息的长度

write 函数

该函数用于在一条已经建立的连接上发送数据,通常使用在 TCP程序中,但在 UDP程序中也能使用。该函数本质上是基于前面介绍的 send 函数来实现的,其参数的意义与 send 也相同。当函数调用成功时,返回成功发送的字节数;否则返回-1。

read()/recv()/recvfrom()函数

函数 recvfrom和 recv用来从一个套接字中接收数据,该函数可以在 UDP 程序使用,也可在TCP 程序中使用。该函数本质上是被函数 netconn_recv 的封装,其参数与函数 sendto 的参数完全相似,如下表所示,数据发送方的地址信息会被填写到 from 中, fromlen 指明了缓存 from 的长度; mem 和 len 分别记录了接收数据的缓存起始地址和缓存长度, flags 指明用户控制接收的方式,通常设置为 0。两个函数的原型如下源码所示:

#define recv(s,mem,len,flags) lwip_recv(s,mem,len,flags)
#define recvfrom(s,mem,len,flags,from,fromlen) lwip_recvfrom(s,mem,len,flags,from,fromlen)ssize_t lwip_readv(int s, const struct iovec *iov, int iovcnt);
ssize_t lwip_recvfrom(int s, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);#define read(s,mem,len) lwip_read(s,mem,len)
ssize_t lwip_read(int s, void *mem, size_t len);
参数描述
sSocket 接口
mem接收数据的缓存起始地址
len缓存长度
flags用户控制接收的方式,通常设置为 0
from(recvfrom())发送方的地址信息
fromlen(recvfrom())缓存 from 的长度

close 函数

函数 close 作用是关闭套接字,对应的套接字描述符不再有效,与描述符对应的内核结构lwip_socket也将被全部复位。该函数本质上是被 netconn_delete的封装,对于 TCP连接来说,该函数将导致断开握手过程的发生。若调用成功,该函数返回 0;否则返回-1。该函数的原型如下源码所示:

#define close(s) lwip_close(s)
int lwip_close(int s);

相关文章:

ESP32(1)基于ESP32的lwIP了解

ESP32-S3 是一款集成了 Wi-Fi 和蓝牙功能的微控制器,而 lwIP(轻量级 IP)是一个为嵌入式系统设计的开源 TCP/IP 协议栈。通过使用 lwIP 库, ESP32-S3 可以实现与外部网络的通信,包括发送和接收数据包、处理网络连接等。…...

C语言预处理详解

目录 (一)预处理符号 (二)define定义常量和宏 (三)#符号和##符号 (四)undef符号的条件编译 (五)头文件的包括 (一)预处理符号 在…...

python实现接口自动化

代码实现自动化相关理论 代码编写脚本和工具实现脚本区别是啥? 代码: 优点:代码灵活方便缺点:学习成本高 工具: 优点:易上手缺点:灵活度低,有局限性。 总结: 功能脚本:工…...

当Anaconda的安装路径与我想创建的conda虚拟环境路径不一致时,应该怎么操作?

我的anaconda安装在该路径:D:\Program\anaconda3 , 如果我想在F盘创建一个虚拟环境 应该怎么做呢? 若你想在 F 盘创建 Anaconda 虚拟环境,可使用 conda create 命令,并通过 --prefix 参数指定环境路径。以下是详细步骤&#xff1…...

MongoDB慢日志查询及索引创建

MongoDB 的慢日志(Slow Query Log)对于运维和程序员来说都非常重要,因为它直接关系到数据库的性能和应用程序的稳定性。以下分享介绍下MongoDB慢日志查询及索引创建相关的一些笔记。 一,准备 1. 使用 db.currentOp() 实时监控 …...

C语言指针(详细总结)

目录 1.初始C指针 几个重要的概念: 指针的加减 &与* 二级指针 2.指针与数组 指针数组 数组指针变量 一维数组与二维数组传参的本质 ​编辑​编辑 ​编辑 3.指针与函数 函数指针数组 4.指针与结构体 5.野指针以及常见的内存管理错误 常见的内存错…...

服务器部署Kong和Konga过程

前言 最近在想怎么将一个接口给外部提供服务,并且可以根据和对放的关系,设置不同的期限或者服务大小?并且有友好的可视化页面! 这让我了解到了 API 网关,所以我开始研究 Kong 和 Konga 的使用。 实际上我最开始研究的apisix,但是部署了好久因为etcd不支持 http 无法连接…...

stm32第五天按键的基础知识

一:按键连接示意图 按键控制LED灯 软件设计流程 初始化系统 o 初始化GPIO外设时钟 o 初始化按键和LED的引脚 • 检测按键输入电平来控制LED灯 o SW2控制灯开 。 SW3控制灯关 1:key.c工程 #include"key.h" #include"stm32f10x.h"v…...

高主频CPU+RTX4090:AI生图性能优化超150%

概述:消费级高主频CPU搭配 RTX 4090显卡可以显著提高AI生图的性能,相比于企业级CPU具有更大的吞吐量和更优的成本效益。 引言:在AI图像生成过程中,CPU与GPU的协同效应对系统的整体性能至关重要。测试表明,与RTX 4090显…...

自学Python创建强大AI:从入门到实现DeepSeek级别的AI

人工智能(AI)是当今科技领域最热门的方向之一,而Python是AI开发的首选语言。无论是机器学习、深度学习还是自然语言处理,Python都提供了丰富的库和工具。如果你梦想创建一个像DeepSeek这样强大的AI系统,本文将为你提供…...

主流区块链

文章目录 主流链1. Solana特点:适用场景:工具链: 2. Binance Smart Chain (BSC)特点:适用场景:工具链: 3. Avalanche特点:适用场景:工具链: 4. Polkadot特点:…...

DevEco Studio的使用

目录 1.创建ArkTS工程 2.ArkTS工程目录结构(Stage模型) 构建第一个页面 构建第二个页面 实现页面间的跳转 1.创建ArkTS工程 若首次打开DevEco Studio,请点击Create Project创建工程。如果已经打开了一个工程,请在菜单栏选择…...

Oracle 公布 Java 的五大新功能

Java 增强提案包括语言增强和性能优化,从 JDK 25 中的稳定值 API 开始。 随着JDK(Java 开发工具包)24刚刚全面上市,Oracle 提前透露了不久的将来即将推出的 Java 功能,包括增强原始装箱到空限制值类类型。 3 月 18 日…...

checkpoint机制

1、什么是checkpoint 将缓冲池中的脏页刷新到磁盘,并更新redo log的checkpoint位点,确保数据库在发生故障时可以快速恢复到一致的状态。 2、checkpoint执行过程 确保需要刷新的脏页:从缓冲池中选取一部分需要刷新的页数据页刷新&#xff1…...

MySQL函数大全(持续更新)

MySQL常用函数 一、字符串函数 函数功能 CONCAT(s1, s2, ...) 拼接字符串 CONCAT_WS(sep, s1, s2, ...) 指定分隔符拼接字符串 SUBSTRING(str, start, length) 截取字符串 LEFT(str, length) 从左边截取指定长度字符串 RIGHT(str, length) 从右边截取指定长度字符串 LENGTH(s…...

商业智能BI分析中,汽车4S销售行业的返厂频次有什么分析价值?

买过车的朋友会发现,同一款车不管在哪个4S店去买,基本上价格都相差不大。即使有些差别,也是带着附加条件的,比如要做些加装需要额外再付一下费用。为什么汽车4S销售行业需要商业智能BI?就是因为在汽车4S销售行业&#…...

51单片机程序变量作用域问题

问题&#xff1a; //为什么下面这个程序可以运行 #include <REGX52.H> #include "LCD1602.h" #include "Delay.h" unsigned int result 0; void main(){LCD_Init();while(1){LCD_ShowNum(1,1,result,3);Delay(200);result;}; } //但是这样会报错&a…...

力扣算法ing(33 / 100)

3.20 146.LRU缓存 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中&#xff0c;则返回关键字的值&…...

基于springboot的母婴商城系统(018)

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本母婴商城系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&am…...

【数学建模】模糊综合评价模型详解、模糊集合论简介

模糊综合评价模型详解 文章目录 模糊综合评价模型详解1. 模糊综合评价模型概述2. 模糊综合评价的基本原理2.1 基本概念2.2 评价步骤 3. 模糊综合评价的数学模型3.1 数学表达3.2 模糊合成运算 4. 模糊综合评价的应用领域5. 模糊综合评价的优缺点5.1 优点5.2 缺点 6. 模糊综合评价…...

BSCAN2-1:load design

1. DFT Flow Using Tessent Shell Tessent BoundaryScan 具有一个基本的高层次流程顺序。下图展示了将 Tessent BoundaryScan 插入设计所需的高层次步骤顺序。图中的每个步骤都链接到有关可测试性设计&#xff08;DFT&#xff09;流程的更详细信息&#xff0c;包括示例。 Desi…...

Pytorch中layernorm实现详解

平时我们在编写神经网络时&#xff0c;经常会用到layernorm这个函数来加快网络的收敛速度。那layernorm到底在哪个维度上进行归一化的呢&#xff1f; 一、问题描述 首先借用知乎上的一张图&#xff0c;原文写的也非常好&#xff0c;大家有空可以去阅读一下&#xff0c;链接放…...

Redis HyperLogLog

Redis HyperLogLog HyperLogLog 是 Redis 提供的一种基数估算&#xff08;Cardinality Estimation&#xff09;数据结构&#xff0c;专门用于统计去重元素的数量&#xff08;近似值&#xff09;。 1. HyperLogLog 特点 ✅ 节省内存&#xff1a;无论存储的元素有 10 个 还是 …...

【微服务日志收集①】使用FileBeat+Logstash+ES搭建ELK日志系统

使用FileBeatLogstashES搭建ELK日志系统&#xff0c;架构图如下&#xff1a; 1、 使用docker快速创建ES服务和Kibana服务 前置条件&#xff1a;需要在linux上提前安装好docker和docker-compose 1.1、在linux创建好一个用于存放docker-compose配置文件的文件夹 我的目录是/app/…...

【FAQ】HarmonyOS SDK 闭源开放能力 —Push Kit(10)

1.问题描述&#xff1a; 离线推送&#xff0c;锁屏的时候没有弹出消息&#xff0c;只有下拉在通知中心里面显示。请问是否是正常的&#xff1f; 解决方案&#xff1a; 检查一下是否存在图片风控&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-referen…...

Django之旅:第二节--启动运行django

1、确保app已配置完(settings.py文件里面配置&#xff09; INSTALLED_APPS [django.contrib.admin,django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,django.contrib.messages,django.contrib.staticfiles,app.apps.AppConfig #配置已经注册好的app…...

Redis Sentinel(哨兵模式)高可用性解决方案

一、概述 Redis Sentinel&#xff08;哨兵模式&#xff09;是Redis的高可用性&#xff08;High Availability, HA&#xff09;解决方案&#xff0c;它通过哨兵系统和Redis实例的协同工作&#xff0c;确保了Redis服务的高可用性和数据的持久性。哨兵系统由一个或多个哨兵进程组…...

Redis缓存与数据库 数据一致性保障

为什么要保证数据一致性 只要使用redis做缓存&#xff0c;就必然存在缓存和DB数据一致性问题。若数据不一致&#xff0c;则业务应用从缓存读取的数据就不是最新数据&#xff0c;可能导致严重错误。比如将商品的库存缓存在Redis&#xff0c;若库存数量不对&#xff0c;则下单时…...

Grid 布局实现三栏布局

使用 CSS Grid 布局实现三栏布局(左右固定 100px,中间自适应)的核心原理是通过网格模板精确控制列宽分配。以下是具体实现方法及优化技巧: 一、基础实现 ​父容器设置 为外层容器添加 display: grid 使其成为网格容器,并通过 grid-template-columns 定义列宽 css .contain…...

如何在 HTML 中创建一个有序列表和无序列表,它们的语义有何不同?

大白话如何在 HTML 中创建一个有序列表和无序列表&#xff0c;它们的语义有何不同&#xff1f; 1. HTML 中有序列表和无序列表的基本概念 在 HTML 里&#xff0c;列表是一种用来组织信息的方式。有序列表就是带有编号的列表&#xff0c;它可以让内容按照一定的顺序呈现&#…...

springboot第三站(1) web开发引入

目录 1.简介 2.SpringBoot对静态资源的映射规则 3.模版引擎 1.简介 使用SpringBoot&#xff1b; 1&#xff09;、创建SpringBoot应用&#xff0c;选中我们需要的模块&#xff1b; 2&#xff09;、SpringBoot已经默认将这些场景配置好了&#xff0c;只需要在配置文件中指定…...

nginx 简单实践:负载均衡【nginx 实践系列之四】

〇、前言 本文为 nginx 简单实践系列文章之三&#xff0c;主要简单实践了负载均衡&#xff0c;仅供参考。 注意&#xff1a;可以使用测试域名&#xff0c;但前提是要修改 hosts 文件 路径和重启&#xff1a;Linux&#xff08;/etc/hosts&#xff09;&#xff08;重启命令&#…...

CentOS 7.9 安装 Python 3.10 详细步骤及常见问题解决

一、环境准备与依赖安装 更新系统与开发工具 sudo yum update -y sudo yum groupinstall "Development Tools" -y sudo yum install -y zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel \ readline-devel tk-devel libffi-devel gdbm-devel db4-de…...

计算机网络-1-1计算机网络体系结构

第一章计算机网络体系结构 绪论 《计算机网络》学什么&#xff1f;——数据如何通过网络正确、可靠地从A传送到B 【考纲内容】 (一)计算机网络概述 计算机网络的概念、组成与功能&#xff1b;计算机网络的分类&#xff1b; 计算机网络的性能指标 (二)计算机网…...

集装箱箱号OCR识别技术,在铁路物流场站集装箱装卸机械数字化系统中的应用

集装箱装卸机械数字化是针对铁路物流场站的门式起重机、集装箱正面吊运起重机、重型叉车、堆高机等作业设备&#xff0c;在不影响原设备作业性能情况下&#xff0c;通过增加或集成集装箱箱号OCR识别或者车号识别装置、北斗定位装置、PLC采集装置等&#xff0c;利用多种通信协议…...

数仓工具—Hive语法之不同纬度聚合

不同纬度聚合 提到不同纬度聚合,大家想到的肯定是grouping sets,或者是cube和rollup 其实这些我们之前都讲过,可以看看之前的文章 数仓工具—Hive语法之cube和rollup 数仓工具—Hive语法之grouping sets 但是我们今天遇到的问题是,使用的工具不支持grouping sets,既然…...

GitHub在push推送到远程仓库的时候显示Logon failed登录失败

具体问题描述 git.exe push --progress "origin" master:master Logon failed, use ctrlc to cancel basic credential prompt. remote: Support for password authentication was removed on August 13, 2021. 这是因为Git 推送失败的原因是 GitHub 已经不支持密码认…...

【Dive Into Stable Diffusion v3.5】1:开源项目正式发布——深入探索SDv3.5模型全参/LoRA/RLHF训练

目录 1 引言2 项目简介3 快速上手3.1 下载代码3.2 环境配置3.3 项目结构3.4 下载模型与数据集3.5 运行指令3.6 核心参数说明3.6.1 通用参数3.6.2 优化器/学习率3.6.3 数据相关 4 结语 1 引言 在人工智能和机器学习领域&#xff0c;生成模型的应用越来越广泛。Stable Diffusion…...

2025-03-19 Unity 网络基础2——网络通信基础

文章目录 1 数据通信模型1.1 C/S 模型1.2 B/S 模型1.3 P2P 模型1.4 小结 2 网络协议2.1 OSI 模型2.1.1 下层2.1.2 上层 2.2 TCP/IP 协议2.2.1 TCP 协议2.2.2 UDP 协议 3 网络游戏通信方案3.1 强/弱弱联网游戏3.2 长/短连接游戏3.3 相关术语 1 数据通信模型 ​ 在早期的计算机网…...

路由器安全研究:D-Link DIR-823G v1.02 B05 复现与利用思路

前言 D-Link DIR-823G v1.02 B05存在命令注入漏洞&#xff0c;攻击者可以通过POST的方式往 /HNAP1发送精心构造的请求&#xff0c;执行任意的操作系统命令。 漏洞分析 binwalk提取固件&#xff0c;成功获取到固件。 现在我们已经进入到应用里了&#xff0c;那么我们在进行分析…...

【蓝桥杯python研究生组备赛】005 数学与简单DP

题目1 01背包 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式 第一行两个整数&a…...

数据仓库是什么,跟数据集成有什么关系

在当今数字化时代&#xff0c;数据已成为企业决策的重要依据。数据仓库作为企业数据管理的核心组件&#xff0c;其重要性不言而喻。那么&#xff0c;数据仓库到底是什么&#xff1f;它与数据集成又有着怎样的关系呢&#xff1f;本文将深入探讨这些问题。 一、数据仓库&#xf…...

鸿蒙NEXT项目实战-百得知识库01

代码仓地址&#xff0c;大家记得点个star IbestKnowTeach: 百得知识库基于鸿蒙NEXT稳定版实现的一款企业级开发项目案例。 本案例涉及到多个鸿蒙相关技术知识点&#xff1a; 1、布局 2、配置文件 3、组件的封装和使用 4、路由的使用 5、请求响应拦截器的封装 6、位置服务 7、三…...

【微服务】SpringBoot整合LangChain4j 操作AI大模型实战详解

目录 一、前言 二、Langchain4j概述 2.1 Langchain4j 介绍 2.1.1 Langchain4j 是什么 2.1.2 主要特点 2.2 Langchain4j 核心组件介绍 2.3 Langchain4j 核心优势 2.4 Langchain4j 核心应用场景 三、SpringBoot 整合 LangChain4j 组件使用 3.1 前置准备 3.1.1 获取apik…...

rust学习笔记16-206.反转链表(递归)

rust函数递归在14中已经提到&#xff0c;接下来我们把206.反转链表&#xff0c;用递归法实现 递归函数通常包含两个主要部分&#xff1a; 基准条件&#xff08;Base Case&#xff09;&#xff1a;递归终止的条件&#xff0c;避免无限递归。 递归步骤&#xff08;Recursive Ste…...

Unity 中实例化预制体的完整过程

1.资源加载&#xff08;Load Asset to Memory&#xff09; Unity 的资源加载是指将各种资源&#xff08;如模型、纹理、音频、预制体 等&#xff09;从存储介质&#xff08;如磁盘、AssetBundle、远程服务器&#xff09;到运行时内存的过程&#xff0c;使其成为可用的资源&…...

Unity动画片段丢失(AnimationClip),如何进行重新绑定

从外部导入的AnimationClip存在黄色丢失的missing提示&#xff0c;这时候不需要重新制作动画&#xff0c;只需要重新绑定动画即可。 我们以第一条Intro1:Anchored Position(缺失!)为例 第一步&#xff1a;双击动画中的Intro1条目&#xff0c;可以查看片段存储该动画的对应路径…...

mysql5.7主从部署(docker-compose版本)

mysql5.7主从部署&#xff08;docker-compose版本&#xff09; 1:docker-compose-test.yml 文件信息 version: 3services:# MySQL 数据库mysql-master:image: mysql:5.7container_name: mysql-masterenvironment:MYSQL_ROOT_PASSWORD: 123456MYSQL_DATABASE: nacosports:- 23…...

模型部署实战:PyTorch生产化指南

‌一、为什么要做模型部署&#xff1f;‌ 模型部署是将训练好的模型‌投入实际应用‌的关键步骤&#xff0c;涉及&#xff1a; 模型格式转换&#xff08;TorchScript/ONNX&#xff09;性能优化&#xff08;量化/剪枝&#xff09;构建API服务移动端集成 本章使用ResNet18实现图…...

SQLMesh 系列教程:Airbnb数据分析项目实战

在本文中&#xff0c;我们将探讨如何利用dbt项目的代码库来实现一个简单的SQLMesh项目。本文的基础是基于Udemy讲师为dbt课程创建的示例项目&#xff0c;可以在这个GitHub repo中获得。这个dbt项目是相对完整的示例&#xff0c;我们将使用它作为模板来演示SQLMesh&#xff08;下…...