Linux之netlink(2)libnl使用介绍(1)
Linux之netlink(2)Libnl3使用介绍(1)
Author:Onceday Date:2025年4月26日
漫漫长路,才刚刚开始…
全系列文章可查看专栏: Linux内核知识_Once-Day的博客-CSDN博客
本文翻译自libnl3官方文档:Netlink Library (libnl)
参考文档:
- thom311/libnl: Netlink Library Suite
- libnl - Netlink Protocol Library Suite
- Routing Family Netlink Library (libnl-route)
- Netlink Library (libnl)
- Documentation Overview - libnl Suite
文章目录
- Linux之netlink(2)Libnl3使用介绍(1)
- 1. libnl介绍
- 2. Netlink协议介绍
- 2.1 Netlink地址
- 2.2 消息格式
- 2.3 消息类型
- 2.4 序列号
- 3. Netlink套接字
- 3.1 Socket实例
- 3.2 序列号
- 3.3 多播组
- 3.4 回调函数配置
- 3.5 套接字属性
1. libnl介绍
libnl3是Linux平台上一个功能丰富的网络编程库。它为用户空间程序提供了一组全面的API,用于与Linux内核的网络组件进行交互。libnl3让开发者能够方便地配置和管理各种网络功能,如链路、接口、路由、地址、邻居、策略路由、流量控制、网络状态监控等。
libnl 套件是一组库的集合,它为基于 Netlink 协议的 Linux 内核接口提供了应用程序编程接口(API)。
Netlink 是一种主要在内核与用户空间进程之间使用的进程间通信(IPC)机制。它被设计成是 ioctl(输入输出控制)更灵活的替代方案,主要用于提供与网络相关的内核配置和监控接口。
这些接口被划分到几个小型库中,这样就不会强制应用程序链接到一个庞大臃肿的单一库上。
- libnl,核心库,实现了使用 Netlink 协议所需的基本功能,比如套接字处理、消息构建与解析,以及数据的发送和接收。这个库保持小巧且简约。该套件中的其他库都依赖于这个库。
- libnl-route,提供了 NETLINK_ROUTE 系列配置接口的 API,这些接口涉及网络接口、路由、地址、邻居节点以及流量控制等方面。
- libnl-genl,提供了通用 Netlink 协议(Netlink 协议的扩展版本)的 API。
- libnl-nf,提供了基于 Netlink 的 netfilter(网络过滤器)配置和监控接口(连接跟踪、日志记录、队列)的 API。
主要的头文件是 <netlink/netlink.h>
。根据程序所使用的子系统和组件的不同,可能还需要在源文件中包含其他的头文件。
#include <netlink/netlink.h>#include <netlink/cache.h>#include <netlink/route/link.h>
如果该库在编译时启用了调试语句,那么当环境变量 NLDBG 的值设置为大于 0 时,它将会把调试信息打印到标准错误输出(stderr)中。
NLDBG=2 ./myprogram
下面是各个NLDBG值对应的调试级别:
调试级别 | 描述 |
---|---|
0 | 调试功能已禁用(默认设置) |
1 | 警告、重要事件及通知信息 |
2 | 或多或少较为重要的调试消息 |
3 | 会产生大量调试消息的重复性事件相关信息 |
4 | 甚至更不太重要的消息 |
查看与其他套接字交换的 Netlink 消息流通常是很有用的。设置环境变量 NLCB=debug 将启用调试消息处理程序,该程序进而会以人类可读的格式将交换的 Netlink 消息打印到标准错误输出(stderr)中。
$ NLCB=debug ./myprogram-- Debug: Sent Message:-------------------------- BEGIN NETLINK MESSAGE ---------------------------[HEADER] 16 octets.nlmsg_len = 20.nlmsg_type = 18 <route/link::get>.nlmsg_flags = 773 <REQUEST,ACK,ROOT,MATCH>.nlmsg_seq = 1301410712.nlmsg_pid = 20014[PAYLOAD] 16 octets
.....
2. Netlink协议介绍
2.1 Netlink地址
Netlink 协议是一种基于套接字的进程间通信(IPC)机制,用于用户空间进程与内核之间,或者用户空间进程彼此之间的通信。Netlink 协议基于 BSD 套接字,并使用 AF_NETLINK 地址族。每一种 Netlink 协议都有其自身的协议编号(例如,NETLINK_ROUTE、NETLINK_NETFILTER 等)。它的编址模式基于一个 32 位的端口号,以前称为进程标识符(PID),这个端口号唯一标识每个通信对等端。
Netlink 地址(端口)由一个 32 位整数组成。端口 0(零)是为内核保留的,它指的是每个 Netlink 协议族在内核端的套接字。其他端口号通常指的是用户空间所拥有的套接字,不过这并非强制规定。
起初,常见的做法是使用进程标识符(PID)作为本地端口号。但随着支持多线程的 Netlink 应用程序以及需要多个套接字的应用程序的出现,这种做法变得不太实用了。因此,libnl 库会基于进程标识符生成唯一的端口号,并为其添加一个偏移量,从而允许使用多个套接字。出于向后兼容的原因,初始套接字的端口号仍然会等于进程标识符。
上图展示了三个应用程序以及内核端所暴露的两个内核端套接字。它呈现了常见的 Netlink 使用场景:
- 用户空间到内核。
- 用户空间到用户空间。
- 监听内核的多播通知。
(1)用户空间到内核:Netlink 最常见的使用形式是用户空间应用程序向内核发送请求,并处理回复,回复内容要么是错误消息,要么是成功通知。
(2)用户空间到用户空间:Netlink 也可以用作一种进程间通信机制,以便用户空间应用程序之间直接进行通信。通信并不局限于两个对等端,任意数量的对等端都可以相互通信,并且多播功能允许通过一条消息发送给多个对等端。
为了让各个套接字能够相互可见,必须为相同的 Netlink 协议族创建这两个套接字。
(3)用户空间监听内核通知:这种形式的 Netlink 通信通常出现在用户空间守护进程中,这些守护进程需要针对某些内核事件采取行动。此类守护进程通常会维护一个订阅了某个多播组的 Netlink 套接字,内核使用该多播组向感兴趣的用户空间各方通知特定事件。
由于在任何时候更换用户空间组件时都无需内核察觉,并且具有灵活性,所以相较于直接编址,多播的使用更为可取。
2.2 消息格式
Netlink 协议通常基于消息,由 Netlink 消息头部(struct nlmsghdr
)以及附加到它上面的有效载荷组成。有效载荷可以由任意数据构成,但通常包含一个固定大小的特定于协议的头部,其后跟着一系列属性。
Netlink 消息头部(struct nlmsghdr
结构体):
-
总长度(32 位):消息的总长度,以字节为单位,包括 Netlink 消息头部。
-
消息类型(16 位):消息类型指定了该消息所携带的有效载荷的类型。Netlink 协议定义了几种标准的消息类型。每个协议族可能会定义额外的消息类型。
-
消息标志(16 位):消息标志可用于修改消息类型的行为。
-
序列号(32 位):序列号是可选的,可用于引用先前的消息,例如,一条错误消息可以引用导致该错误的原始请求。
-
端口号(32 位):端口号指定了该消息应发送到的对等端。如果未指定端口号,该消息将被发送到同一协议族中第一个匹配的内核端套接字。
2.3 消息类型
Netlink 协议区分请求、通知和回复。请求是设置了NLM_F_REQUEST
标志的消息,其目的是向接收方请求执行某个操作。请求通常由用户空间进程发送到内核。虽然并非严格强制要求,但每个发送的请求都应该携带一个递增的序列号。
根据请求的性质,接收方可能会用另一条 Netlink 消息来回复该请求。回复的序列号必须与它所关联的请求的序列号相匹配。
通知属于非正规性质的消息,不需要回复,因此序列号通常设置为 0。
消息的类型主要通过消息头部中设置的 16 位消息类型来识别。定义了以下标准消息类型:
-
NLMSG_NOOP,无操作,该消息必须被丢弃。
-
NLMSG_ERROR,错误消息或确认消息(ACK)。
-
NLMSG_DONE,多部分消息序列的结束。
-
NLMSG_OVERRUN,溢出通知(错误)。
每个 Netlink 协议都可以自由定义自己的消息类型。请注意,小于 NLMSG_MIN_TYPE(0x10)的消息类型值是保留的,不能使用。
通常的做法是使用自定义的消息类型来实现远程过程调用(RPC)模式。假设正在实现的 Netlink 协议的目标是允许对特定网络设备进行配置,因此希望提供对各种配置选项的读写访问权限。实现这一目标的典型 “Netlink 方式” 是定义两种消息类型:MSG_SETCFG(设置配置消息)和 MSG_GETCFG(获取配置消息):
#define MSG_SETCFG 0x11
#define MSG_GETCFG 0x12
发送一条MSG_GETCFG
请求消息通常会触发一条消息类型为MSG_SETCFG
的回复,回复中包含当前的配置信息。用面向对象的术语来说,这可以描述为 “内核在用户空间中设置配置的本地副本”。
可以通过发送一条 MSG_SETCFG 消息来更改配置,对该消息的回复要么是一条确认消息(ACK),要么是一条错误消息。
作为可选操作,内核可以发送配置更改的通知,使用户空间能够监听这些更改,而无需频繁轮询。通知通常会重用现有的消息类型,并且依赖于应用程序使用单独的套接字来区分请求和通知,但你也可以指定一个单独的消息类型。
尽管从理论上讲,一条 Netlink 消息的大小最大可达 4GiB,但套接字缓冲区很可能不够大,无法容纳如此大小的消息。因此,通常的做法是将消息大小限制为一页的大小(PAGE_SIZE),并使用多部分机制将大块数据分割成几条消息。一条多部分消息(Multipart Messages)设置了标志NLM_F_MULTI
,接收方需要持续接收和解析消息,直到接收到特殊的消息类型NLMSG_DONE
为止。
与分片的 IP 数据包不同,多部分消息无需重新组装,尽管如果协议希望以这种方式工作,重新组装也是完全可行的。多部分消息常常用于发送对象列表或对象树,每条多部分消息仅仅携带多个对象,从而允许独立解析每条消息。
错误消息可以作为对请求的响应而发送。错误消息必须使用标准消息类型 NLMSG_ERROR。其有效载荷由一个错误代码和原始请求的 Netlink 消息头部组成。
错误消息应将序列号设置为导致该错误的请求的序列号。
确认消息(ACK),发送方可以通过在请求中设置 NLM_F_ACK 标志,来请求接收方为每条已处理的请求发回一条确认消息。这通常用于让发送方在请求被接收方处理之前同步后续的处理操作。
确认消息也使用消息类型NLMSG_ERROR
和有效载荷格式,但错误代码设置为 0。
消息标志,定义了以下标准标志:
#define NLM_F_REQUEST 1
#define NLM_F_MULTI 2
#define NLM_F_ACK 4
#define NLM_F_ECHO 8
- NLM_F_REQUEST - 消息是一个请求。
- NLM_F_MULTI - 多部分消息。
- NLM_F_ACK - 请求确认消息。
- NLM_F_ECHO - 请求回显该请求。
标志 NLM_F_ECHO 与 NLM_F_ACK 标志类似。它可以与 NLM_F_REQUEST 标志结合使用,使得作为请求结果而发送的通知,无论发送方是否已订阅相应的多播组,都会被发送给发送方。
还定义了一些仅适用于 GET 请求的额外通用消息标志:
#define NLM_F_ROOT 0x100
#define NLM_F_MATCH 0x200
#define NLM_F_ATOMIC 0x400
#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH)
- NLM_F_ROOT - 基于树的根节点返回数据。
- NLM_F_MATCH - 返回所有匹配的条目。
- NLM_F_ATOMIC - 已过时,曾经用于请求一个原子操作。
- NLM_F_DUMP - 返回所有对象的列表(NLM_F_ROOT|NLM_F_MATCH)。
这些标志的使用完全是可选的,许多 Netlink 协议仅使用 NLM_F_DUMP 标志,该标志通常请求接收方以多部分消息序列的形式,发送与消息类型相关的所有对象的列表。
还有另一组与 NEW 或 SET 请求相关的标志。这些标志与 GET 请求的标志相互排斥:
#define NLM_F_REPLACE 0x100
#define NLM_F_EXCL 0x200
#define NLM_F_CREATE 0x400
#define NLM_F_APPEND 0x800
- NLM_F_REPLACE - 如果对象已存在,则替换该现有对象。
- NLM_F_EXCL - 如果对象已经存在,则不更新该对象。
- NLM_F_CREATE - 如果对象尚不存在,则创建该对象。
- NLM_F_APPEND - 在列表末尾添加对象。
这些标志的行为在不同的 Netlink 协议之间可能会略有不同。
2.4 序列号
Netlink 允许使用序列号来帮助将回复与请求相关联。需要注意的是,与 TCP 等协议不同,Netlink 对序列号没有严格的强制要求。序列号的唯一目的是帮助发送方将回复与相应的请求关联起来。序列号是在每个套接字的基础上进行管理的。
3. Netlink套接字
3.1 Socket实例
为了使用 Netlink 协议,需要一个 Netlink 套接字。每个套接字都定义了一个独立的消息发送和接收上下文。一个应用程序可以使用多个套接字,例如,一个套接字用于发送请求并接收回复,另一个套接字订阅多播组以接收通知。
Netlink 套接字以及所有相关属性(包括实际的文件描述符)都由struct nl_sock
结构体表示。
#include <netlink/socket.h>struct nl_sock *nl_socket_alloc(void)
void nl_socket_free(struct nl_sock *sk)
应用程序必须为其希望使用的每个 Netlink 套接字分配一个struct nl_sock
结构体的实例。
3.2 序列号
该库会自动为应用程序处理序列号。在套接字结构中存储有一个序列号计数器,当需要发送预期会产生回复(如错误消息或任何其他需要与原始消息相关联的消息类型)的消息时,会自动使用并递增该计数器。
或者,也可以通过函数nl_socket_use_seq()
直接使用该计数器。它将返回计数器的当前值,然后将其递增 1。
#include <netlink/socket.h>unsigned int nl_socket_use_seq(struct nl_sock *sk);
不过,大多数应用程序并不希望自己处理序列号。当使用nl_send_auto()
函数时,序列号会自动填入,并且在收到回复时会再次进行匹配。
如果所实现的 Netlink 协议不使用请求 / 回复模型,例如当套接字用于接收通知消息时,这种(自动处理序列号的)行为可以并且必须被禁用。
#include <netlink/socket.h>void nl_socket_disable_seq_check(struct nl_sock *sk);
3.3 多播组
每个套接字可以订阅其所连接的 Netlink 协议的任意数量的多播组。然后,该套接字将接收发送到任何一个多播组的每条消息的副本。多播组通常用于实现事件通知。
在内核版本 2.6.14 之前,组订阅是使用位掩码来执行的,这将每个协议族的组数量限制为 32 个。即使不建议在新代码中使用,仍然可以通过函数nl_join_groups()
访问这个过时的接口。
#include <netlink/socket.h>void nl_join_groups(struct nl_sock *sk, int bitmask);
从内核版本 2.6.14 开始引入了一种新方法,该方法支持订阅几乎无限数量的多播组。
#include <netlink/socket.h>int nl_socket_add_memberships(struct nl_sock *sk, int group, ...);
int nl_socket_drop_memberships(struct nl_sock *sk, int group, ...);
3.4 回调函数配置
每个套接字都被分配一个回调配置,该配置控制套接字的行为。例如,这对于每个套接字拥有一个单独的消息接收函数是必要的。不过,在套接字之间共享回调配置也是完全可行的。
可以使用以下函数来访问和设置套接字的回调配置:
#include <netlink/socket.h>struct nl_cb *nl_socket_get_cb(const struct nl_sock *sk);
void nl_socket_set_cb(struct nl_sock *sk, struct nl_cb *cb);
此外,还存在一种快捷方式,可以直接修改分配给套接字的回调配置:
#include <netlink/socket.h>int nl_socket_modify_cb(struct nl_sock *sk, enum nl_cb_type type, enum nl_cb_kind kind,nl_recvmsg_msg_cb_t func, void *arg);
3.5 套接字属性
本地端口号唯一标识该套接字,并用于对其进行寻址。在分配套接字时,会自动生成一个唯一的本地端口号。它将由进程 ID(22 位)和一个随机数(10 位)组成,因此每个进程最多允许有 1024 个套接字。
#include <netlink/socket.h>uint32_t nl_socket_get_local_port(const struct nl_sock *sk);
void nl_socket_set_local_port(struct nl_sock *sk, uint32_t port);
注意:可以覆盖本地端口号,但你必须确保所提供的值是唯一的,并且任何其他应用程序中的其他套接字都没有使用相同的值。
可以为套接字分配一个对等端口,这将导致通过该套接字发送的所有单播消息都被发送到该对等方。如果未指定对等方,则消息将发送到内核,内核将尝试自动将该套接字绑定到同一 Netlink 协议族的内核端套接字。通常的做法是不将套接字绑定到对等端口,因为每个 Netlink 协议族通常只存在一个内核端套接字。
#include <netlink/socket.h>uint32_t nl_socket_get_peer_port(const struct nl_sock *sk);
void nl_socket_set_peer_port(struct nl_sock *sk, uint32_t port);
Netlink 使用 BSD 套接字接口,因此每个套接字背后都有一个文件描述符,你可以直接使用它。
#include <netlink/socket.h>int nl_socket_get_fd(const struct nl_sock *sk);
如果一个套接字仅用于接收通知,通常最好将该套接字设置为非阻塞模式,并定期轮询以获取新的通知。
#include <netlink/socket.h>int nl_socket_set_nonblocking(const struct nl_sock *sk);
套接字缓冲区用于在发送方和接收方之间对 Netlink 消息进行排队。这些缓冲区的大小指定了你能够写入 Netlink 套接字的最大大小,也就是说,它将间接定义最大消息大小。默认大小是 32KiB。
#include <netlink/socket.h>int nl_socket_set_buffer_size(struct nl_sock *sk, int rx, int tx);
以下函数允许在套接字上启用 / 禁用自动确认模式。自动确认模式默认是启用的。
#include <netlink/socket.h>void nl_socket_enable_auto_ack(struct nl_sock *sk);
void nl_socket_disable_auto_ack(struct nl_sock *sk);
启用/禁用消息窥探(Message Peeking)。如果启用,消息窥探会使nl_recv函数尝试使用 MSG_PEEK 来检索接收到的下一条消息的大小,并分配一个该大小的缓冲区。消息窥探默认是启用的,但可以使用以下函数将其禁用:
#include <netlink/socket.h>void nl_socket_enable_msg_peek(struct nl_sock *sk);
void nl_socket_disable_msg_peek(struct nl_sock *sk);
启用 / 禁用接收数据包信息。如果启用,从内核接收到的每条 Netlink 消息都将在控制消息中包含一个额外的struct nl_pktinfo
结构体。可以使用以下函数来启用 / 禁用接收数据包信息。
#include <netlink/socket.h>int nl_socket_recv_pktinfo(struct nl_sock *sk, int state);
注意,Netlink Pktinfo的处理功能还没有实现。
相关文章:
Linux之netlink(2)libnl使用介绍(1)
Linux之netlink(2)Libnl3使用介绍(1) Author:Onceday Date:2025年4月26日 漫漫长路,才刚刚开始… 全系列文章可查看专栏: Linux内核知识_Once-Day的博客-CSDN博客 本文翻译自libnl3官方文档:Netlink Library (libnl) 参考文档…...
【2025 最新前沿 MCP 教程 04】通信渠道:理解 MCP 传输机制
文章目录 1. 开始啦!2. 本地集成与标准输入输出(stdio)3. 通过 HTTP 实现 SSE(服务器发送事件)的远程通信4. 展望未来:向可流式 HTTP 的过渡 1. 开始啦! 在第三章中,我们解析了模型…...
Qt Charts 绘制曲线图示例
Qt Charts 绘制曲线图示例 Qt Charts 是 Qt 的图表模块,可用于绘制折线图、曲线图等。以下是实现步骤: 1. 配置项目文件 在 .pro 文件中添加 Charts 模块: QT charts2. 创建基础图表 #include <QtCharts>// 创建图表视图和图表对…...
统计学_一元线性回归知识点梳理
1 变量间关系的度量 1.1 变量间的关系 (1)相关关系:变量之间是不确定的数量关系,比如农作物产量和施肥量的关系。(2)函数关系:变量之间是一一确定的对应的关系,y 完全依赖于 x。 …...
【计算机视觉】CV项目实战- 深度解析TorchVision_Maskrcnn:基于PyTorch的实例分割实战指南
深度解析TorchVision_Maskrcnn:基于PyTorch的实例分割实战指南 技术背景与核心原理Mask R-CNN架构解析项目特点 完整实战流程环境准备硬件要求软件依赖 数据准备与标注1. 图像采集2. 数据标注3. 数据格式转换 模型构建与训练1. 模型初始化2. 数据加载器配置3. 训练优…...
数据分析岗位-相关知识
数据分析岗位 1.大数据2.业务(朴素理念) 1.大数据 数据流向 :MySQL等传统业务数据(结构、半结构、非结构) → ETL → 数据仓库 / 数据计算 → BI(BI也提供计算能力) sequenceDiagramMySQL->…...
使用 Truffle 和 Ganache 搭建本地以太坊开发环境并部署一个简单智能合约
使用 Truffle 和 Ganache 搭建本地以太坊开发环境并部署一个简单智能合约的详细步骤: 一、环境搭建 安装 Node.js 和 npm Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,npm 是 Node.js 的包管理器。可以从 Node.js 官方网站下载安装程序…...
Set的学习
1. Set是继承自Collection的一个接口类 2. Set中只存储了key,并且要求key一定要唯一 3. TreeSet的底层是使用Map来实现的,其使用key与Object的一个默认对象作为键值对插入到Map中的 4. Set最大的功能就是对集合中的元素进行去重 5. 实现Set接口的常用…...
Python爬虫实战:获取高考资源网各学科精品复习资料
一、引言 高考资源网拥有丰富的高考复习资料,对于我们而言,获取这些资源并整理分享能为考生提供有价值的帮助。然而,手动从网站查找和下载资源效率低且易出错。利用 Python 爬虫技术可实现自动化资源获取,提高工作效率。但在爬取过程中,需考虑网站反爬机制,采取相应措施…...
Linux下编译并打包MNN项目迁移至其他设备
1. 构建项目结构 该项目是利用MNN框架对MTCNN网络进行推理,实现对目标的实时检测 运行环境:Linux 相关库:opencv,MNN 先给出项目的总体结构,如下: mtcnn_mnn/ ├── include/ │ ├── opencv2/ …...
WPF框架中异步、多线程、高性能、零拷贝技术的应用示例
WPF框架中异步、多线程、高性能与零拷贝技术应用示例 一、异步编程在WPF中的应用 1. 异步数据加载(避免UI冻结) // ViewModel中的异步数据加载示例 public class MainViewModel : INotifyPropertyChanged {private ObservableCollection<string> _items;public Obse…...
SpringBoot实现的后端开发
目录 一、设计阶段 1.设计ER图 2.创建数据库表 二、项目环境搭建 1.创建项目 2.在pom.xml中添加依赖 3.配置数据库连接 4.状态码的封装 5.开发自定义异常 6.密码加密 7.规范时间格式展示 8.添加Guava本地缓存 9.JWT 三、构建项目开发 1.创建项目结构 2.开发实…...
IntelliJ IDEA修改实体类成员变量的名称(引入了该实体类的全部文件也会自动更新变量的名称)
文章目录 1. 问题引入2. 修改实体类成员变量的名称2.1 鼠标双击要修改的变量2.2 按下SHIFT F6快捷键 更多 IntelliJ IDEA 的使用技巧可以查看 IntelliJ IDEA 专栏: IntelliJ IDEA 1. 问题引入 在使用IntelliJ IDEA开发项目时,你是否遇到过以下难题 需…...
Weaviate使用入门:从零搭建向量数据库的完整指南
一、Weaviate简介与核心优势 Weaviate是一款开源向量搜索引擎,专为存储和检索高维向量数据设计,支持文本、图像等多种媒体类型。其核心功能包括语义搜索、问答提取、分类等,具备以下独特优势: 低延迟:毫秒级响应时间…...
element ui el-col的高度不一致导致换行
问题:ell-col的高度不一致导致换行,刷新后审查el-col的高度一致 我这边是el-col写的span超过了24,自行换行,测试发现初次进入里面的高度渲染的不一致,有的是51px有的是51.5px 问题原因分析 Flex布局换行机制 Elemen…...
Windows 安装 MongoDB 教程
Windows 安装 MongoDB 教程 MongoDB 是一个开源的 NoSQL 数据库,它使用文档存储模型而不是传统的关系表格。它非常适合需要处理大量数据并且需要高性能、可扩展性的应用场景。下面是如何在 Windows 系统上安装 MongoDB 的详细步骤。 一、准备工作 确保你的 Windo…...
23种设计模式-行为型模式之观察者模式(Java版本)
Java 观察者模式(Observer Pattern)详解 🧠 什么是观察者模式? 观察者模式是一种行为型设计模式,定义对象之间的一种一对多的依赖关系,使得每当一个对象状态发生变化时,所有依赖它的对象都会得…...
从“拼凑”到“构建”:大语言模型系统设计指南!
你有没有试过在没有说明书的情况下组装宜家家具?那种手忙脚乱却又充满期待的感觉,和设计大语言模型(LLM)系统时如出一辙。如果没有一个清晰的计划,很容易陷入混乱。我曾经也一头扎进去,满心期待却又手足无措,被网上那些复杂的架构图搞得晕头转向。于是,我坐下来,把它们…...
云原生--核心组件-容器篇-3-Docker三大核心之--镜像
1、定义与作用 定义: Docker镜像是一个只读的模板,包含运行应用程序所需的所有内容,包括代码、依赖库、环境变量、配置文件等。简单来说,Docker镜像是一个轻量级、独立、可执行的软件包,它包含了运行某个软件所需的所有…...
在QML中获取当前时间、IP和位置(基于网络请求)
目录 引言相关阅读最终效果代码详解1. 基础框架与窗口设置2. IP定位功能实现3. IP获取功能4. 时间更新与应用初始化5. 用户界面布局 总结工程下载 引言 在本文中,我们将探讨如何使用Qt Quick构建一个简单的系统信息显示应用。该应用能够获取当前系统时间、IP地址以…...
Nuxt3中使用UnoCSS指南
Nuxt3中使用UnoCSS指南 UnoCSS是一个高度可定制的、原子化CSS引擎,可以轻松集成到Nuxt3项目中。下面介绍如何在Nuxt3中安装和配置UnoCSS。 安装步骤 安装UnoCSS的Nuxt模块: # 使用pnpm pnpm add -D unocss unocss/nuxt# 使用yarn yarn add -D unocss…...
【计算机网络】TCP的四种拥塞控制算法
TCP(传输控制协议)是互联网协议套件中用于在网络中两个主机之间提供可靠、有序和错误检测数据传输的协议。TCP使用拥塞控制机制来避免网络拥塞,确保网络资源的有效利用。以下是TCP中常见的四种拥塞控制算法: 慢启动(S…...
WebAssembly全栈革命:在Rust与JavaScript之间构建高性能桥梁
一、WASM的全栈渗透图谱 1. 性能临界点的突破 // Rust实现的斐波那契计算 #[wasm_bindgen] pub fn wasm_fib(n: i32) -> i32 {match n {0 > 0,1 > 1,_ > wasm_fib(n-1) wasm_fib(n-2)} }// JavaScript等效实现对比 console.time(js); jsFib(40); // 1024ms cons…...
深度理解linux系统—— 了解操作系统
一、冯诺依曼体系结构 现在我们常见的计算机(笔记本电脑等)和不常见的计算机(服务器)它们都满足冯诺依曼体系。 我们可以把计算机理解成一个个硬件组成的 输入设备:键盘、鼠标、摄像头、网卡、磁盘等输出设备…...
【fork初体验】
文章目录 Linux 实验:深入理解 fork 系统调用一、实验目的二、实验环境三、实验内容与步骤(一)打印进程的进程 ID 和父进程 ID1. 编写程序2. 编译与运行3. 运行结果 (二)使用 fork 系统调用创建进程并加入循环语句1. 编…...
区块链VS传统数据库:金融数据存储的“信任”与“效率”博弈
在金融行业数字化转型的浪潮中,数据存储技术选型已成为核心议题。区块链技术凭借其去中心化、不可篡改等特性强势崛起,而传统数据库(如关系型数据库MySQL、分布式数据库)凭借成熟生态和高效性能仍占据主导地位。如何在两者之间做出…...
Linux渗透测试
Linux渗透测试 比赛题库-Linux渗透测试 文章目录 Linux渗透测试比赛题库-Linux渗透测试 前言一、解题过程1.通过本地PC中渗透测试平台Kali对靶机场景进行系统服务及版本扫描渗透测试,并将该操作显示结果中Apache服务对应的版本信息字符串作为Flag值提交;…...
ORA-02069错误排查实录:从 Database Link 到 Global Names 的陷阱
文章目录 错误重现根因解决方案1.设置GLOBAL_NAMEStrue2.全部业务逻辑放在在远端执行 在日常的 Oracle 数据同步任务中,我们经常透过 Database Link(DBLink) 进行跨数据库查询与写入。某日,我们在执行一段 INSERT INTO … SELECT …...
【CF闯关练习】—— 1200分
🌏博客主页:PH_modest的博客主页 🚩当前专栏:cf闯关练习 💌其他专栏: 🔴每日一题 🟡 C跬步积累 🟢 C语言跬步积累 🌈座右铭:广积粮,缓…...
正则表达式三剑客之——grep和sed
目录 一.grep 1.1定义 1.2核心功能 1.3基本语法 1.4常用选项 二.sed 2.1 定义 2.2 工作原理 2.3 基本语法 2.3.1常用选项 2.3.2sed自身脚本语法 1. 基本组成 2. 地址 3. 命令 2.3.3 sed替换查找 1 基本语法 2.sed替换查找的实例 3.分组后向引用 4 变量调…...
i18n-ai-translate开源程序,可以使用DeepSeek等模型将您的 i18nJSON翻译成任何语言
一、软件介绍 文末提供程序和源码下载 i18n-ai-translate开源程序使用 DeepSeek等模型可以将您的 i18n JSON 翻译成任何语言。 无缝翻译本地化文件。支持嵌套翻译文件的目录。需要i18next样式的JSON 文件(文末一并提供下载)。 二、模式 CSV 模式 三个…...
关于Android Studio的Gradle各项配置
Gradle 构建概览 Android 应用通常使用 Gradle 构建系统构建。在深入了解如何配置 build 之前,我们先来探索 build 背后的概念,以便您全面了解系统。 什么是 build? 构建系统会将源代码转换为可执行应用。构建通常涉及多个工具,用…...
数据安全和合规性市场分析
一、什么是数据安全和合规性 在数据安全和合规性方面,存在着一系列重要的法律、法规和行业标准,这些规定了组织如何收集、存储、处理和保护个人数据及其他敏感信息。企业之所以要遵守这些规定,是出于多方面的考量,既有法律责任&a…...
venv环境基础指令以及常见问题汇总(持续更新)
常见指令 在 Python 原生虚拟环境(venv) 中,没有直接列出所有虚拟环境的命令(因为 venv 不像 Conda 那样有集中管理机制),但可以通过 文件操作 或 脚本 实现类似功能。以下是常用命令和技巧: &…...
思科路由器重分发(RIP动态路由+静态路由)
路由器重分发(RIP动态路由静态路由) 静态路由不能作翻译官 RIP需要宣告自己的ip;还需要帮静态路由也宣告一下开启端口并配置IP地址 RIP路由 Router>en Router#conf t Router(config)#int g0/0 Router(config-if)#no shutdown Router(c…...
产销协同的作用是什么?又如何对各部门发挥作用?
目录 一、产销协同的对象有哪些? 1. 客户需求 2. 市场趋势 3. 供应链伙伴 4. 企业战略目标 二、产销协同的作用是什么? 1. 提高客户满意度 2. 降低企业成本 3. 增强市场竞争力 4. 优化资源配置 三、产销协同对各部门怎么发挥作用?…...
19.【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--单体转微服务--当前项目拆分规划
随着业务规模的不断扩大和系统复杂度的提升,孢子记账系统需要进行微服务架构的转型。本文将详细规划从单体应用向微服务架构迁移的具体方案,包括功能模块分析、服务拆分、技术选型以及实施步骤等内容。通过合理的服务拆分和架构设计,未来我们…...
JFLAP SOFTWARE 编译原理用(自动机绘图)
csdn全是蛆虫,2mb的软件,都在那里搞收费,我就看不惯,我就放出来,那咋了!!! https://pan.baidu.com/s/1IuEfHScynjCCUF5ScF26KA 通过网盘分享的文件:JFLAP7.1.jar 链接: h…...
从 Vue 到 React:React 合成事件
目录 一、什么是 React 合成事件?二、处理流程React 事件系统的大致流程和 Vue 3 的区别 三、用法示例四、SyntheticEvent 的特点五、为什么 React 要统一事件到根节点?1.减少事件监听器数量2. 简化事件解绑逻辑3. 保证一致的行为 六、React 18 后事件系…...
react的fiber 用法
在 React 里,Fiber 是 React 16.x 及后续版本采用的协调算法,它把渲染工作分割成多个小任务,让 React 可以在渲染过程中暂停、恢复和复用任务,以此提升渲染性能与响应能力。在实际开发中,你无需直接操作 Fiber 节点&am…...
深度学习-学习笔记
文章目录 1、概述2、学习笔记2.1、pytorch 的环境配置 1、概述 本篇博客用来记录我学习深度学习的学习笔记 参考视频:PyTorch深度学习快速入门教程 PyTorch 是一个开源的机器学习框架,主要用于构建和训练深度学习模型。 2、学习笔记 2.1、pytorch 的环…...
[创业之路-390]:人力资源 - 社会性生命系统的解构与重构:人的角色嬗变与组织进化论
前言: 人、财、物、信息、机制、流程、制度、方法共同组合了一个持续的消耗资源、持续的价值创造、持续面临生存与发展、遗传与变异的社会性生命系统。 "人"是所有社会性生命系统最最基础性的要素,它弥漫在系统中多维立体空间的不同节点上&am…...
Redis常见面试题——List对象
当然可以!这里我帮你整理了一份【Redis中 List 结构】相关的高频面试题,并附上简明回答: 📚 Redis List 结构面试题(高频总结版) 1. Redis 中的 List 是什么?底层是什么实现的? 答&…...
案例速成GO操作redis,个人笔记
更多个人笔记:(仅供参考,非盈利) gitee: https://gitee.com/harryhack/it_note github: https://github.com/ZHLOVEYY/IT_note 安装redis客户端:go get github.com/redis/go-redis/v9 注意go …...
什么是WebSocket?NGINX如何支持WebSocket协议?
大家好,我是锋哥。今天分享关于【什么是WebSocket?NGINX如何支持WebSocket协议?】面试题。希望对大家有帮助; 什么是WebSocket?NGINX如何支持WebSocket协议? 1000道 互联网大厂Java工程师 精选面试题-Java…...
ssm驾校预约管理系统的设计与实现(源码+lw+部署文档+讲解),源码可白嫖!
摘要 伴随着我国社会的发展,人民生活质量日益提高。在人们出行方式上的体现就是,价格较为昂贵的代步工具——汽车,它的拥有率在我国越来越高了。而汽车的行驶速度很快,并且随着汽车拥有率的增加,城市中行驶和停靠的车…...
babel核心知识点
Babel 是一个 JavaScript 编译器,主要用于将 ECMAScript 2015 版本的代码转换为向后兼容的 JavaScript 代码,以便在旧版本的浏览器或环境中运行。以下是 Babel 的核心知识点: 1. 基本概念 编译器:Babel 本质上是一个编译器&…...
学习笔记(算法学习+Maven)
单调队列优化多重背包 #include <bits/stdc.h> using namespace std; const int M 2010; const int N 20010; int q[N]; int hh 0, tt -1; int f[N]; int g[N]; int v[M], w[M], s[M]; int n, m; int main() { cin >> n >> m; for (int i 1; …...
买币永续合约成全球交易热点,XBIT去中心化交易所平台显著提升市场流动性
在全球加密货币市场日益扩大的背景下,买币永续合约正展现出惊人的增长势头。虽然比特币自2021年黄金时期以来整体兴趣有所减弱,但永续合约市场表现亮眼,专业和机构交易者正从传统日历期货转向这一领域,使得永续合约占据了约66%的未…...
详解 `from datasets import load_dataset`:数据格式、公开数据集与自定义数据集实战指南
在自然语言处理(NLP)和机器学习领域,Hugging Face 的 datasets 库凭借其高效的数据加载和预处理能力成为开发者必备工具。本文通过代码示例详解 load_dataset 的核心用法,涵盖数据格式解析、公开数据集调用和自定义数据集构建。 一、数据格式解析与加载示例 datasets 库支…...