Linux 内核源码分析---套接字
套接字通信
ISO 设计一种参考模型,定义组成网络的各个层,该模型由7层组成,称为OSI(开放
系统互连)模型如下:
应用层:网络服务与最终用户的接口;
表示层:数据的表示、安全及压缩;格式(jpeg,ascii等);
传话层:建立、管理及终止传话;
传输层:定义传输数据的协议商品,以及流控和差错校验;(数据包一旦离开网卡进入网络传输层);
网络层:进行逻辑地址建起、实现不同网络之间的路由选择;
数据链路层:建立逻辑连接、进行硬件地址寻址、差错检验等等这些功能(由底层网络定义协议),将比特组合成字节进而组合成帧,用MAC地址访问介质,错误发现但不能纠正。
物理层:。。。
核心基本术语
(1) 数据帧(Frame):指起始点和目的点都是数据链路层的信息单元。
(2) 数据包(Packet):指起始点和目的地是网络层的信息单元。
(3) 数据报(Datagram):指起始点和目的地都使用无连接网络服务的网络层的信息单元。
(4) 段(Segment):指起始点和目的地都是传输层的信息单元。
(5) 消息(Message):指起始点和目的地都在网络层以上的信息单元(经常在应用层)。
(6) 元素(Cell):指的是一种固定长度的信息,它的起始点和目的地都是数据链路层。元素通常用于异步传输模式(ATM)和交换多兆位数据服务(SMDS)网络等交换环境。
(7) 数据单元(Data unit):常用的数据单元有服务数据单元(SDU)、协议数据单元(PDU)。
(8) 数据帧:帧数据由两部分组成:帧头部和帧数据,帧头部包括接收方主机物理地址的定位及其它网络信息,帧数据区含有一个数据体。
(9) IP数据体由两个部分组成:数据体头部和数据体的数据区,数据体头部包括IP源地址和IP目标地址及其它信息,数据体的数据区包括用户数据协议、传输控制协议,还有数据包及其它信息。
各层执行任务
主机到网络层负责将信息从一台计算机传输到远程计算机。它处理传输介质的物理性质,并将数据流划分为定长的帧,以便在发生传输错误时重传数据块。假设几台电脑共享 同一传输线程,网络接口卡必须有一个唯一的ID号,MAC 地址。
IP 使用一定格式的地址来寻址计算机,比如:192.168.1.1,这些地址由正式注册权威机构或提供者分配(有时为动态的)。
1、创建套接字
套接字不仅可以用于各种传输协议的IP连接,也可以用于内核支持的所有其他地址和协议类型(例如:IPX、Appletalk、本地UNIX套接字,还有在<socket.h>
中列出的许多其他类型)。
sockaddr
的缺陷是:sa_data把目标地址和端口信息混在一起了
sa_family
是地址家族,一般以”AF_xxx”
形式存在,通常为AF_INET
,代表TCP/IP协议簇sa_data
是14字节协议地址:- 4个字节的无符号整数(IP地址)
- 2个字节的无符号整数(端口号)
sa_data
之所以被定义成14个字节,因为有的协议族使用较长的地址格式。
从 sockaddr 的定义中,无法确定 IP 地址和端口号在这 14 个字节地址空间中的存放位置。因此,进行参数传递时,还需知道这14个字节的空间是如何利用,即哪里放IP地址、哪里放端口号、哪里是空白。
于是,在此基础上,构造了sockaddr_in
的结构体。
/* Structure describing an Internet socket address. */
struct sockaddr_in
{__SOCKADDR_COMMON (sin_family); /* Address family */in_port_t sin_port; /* Port number. */struct in_addr sin_addr; /* Internet address. *//* Pad to size of `struct sockaddr'. */unsigned char sin_zero[sizeof (struct sockaddr) -__SOCKADDR_COMMON_SIZE -sizeof (in_port_t) -sizeof (struct in_addr)]; /* 字符数组sin_zero[8]的存在是为了保证结构体struct sockaddr_in的大小和结构体struct sockaddr的大小相等 */
};
typedef unsigned short int sa_family_t;
#define __SOCKADDR_COMMON(sa_prefix) \sa_family_t sa_prefix##family /*此为整型变量占2字节,主要用于指明地址类型,取值为AF_UNIX|AF_INET|AF_INET6|AF_PACKET等*/
sin_family
指代协议族,在 socket 编程中只能是 AF_INET
;
sin_port
存储端口号(使用网络字节顺序);
sin_addr
存储 IP 地址,使用 in_addr
这个数据结构;
sin_zero
是为了让 sockaddr
与 sockaddr_in
两个数据结构保持大小相同而保留的空字节。
2、使用套接字
如简单的并发服务器模型如下图所示。
在服务器端,主程序提前构建多个子进程,当客户端的请求到来的时候,系统从进程池中选取一个子进程处理客户端的连接,每个子进程处理一个客户端的请求,在全部子进程的处理能力得到满足之前,服务器的网络负载是基本不变的。
BSD网络软件中包含两个重要的函数:inet_addr
,inet_ntoa
。用来在二进制地址格式和点分十进制字符串格式之间转换,仅支持IPv4。也有两个函数同时支持 IPv4 和 IPv6:inet_ntop
,inet_pton
。
3、数据报套接字
UDP 是建立在 IP 连接之上的第二种广泛使用的传输协议。UDP 表示 User Datagram Protocol(用户数据报协议)。UDP通常用于视频会议、音频流及类似的服务。
- UDP是面向分组的,在发送数据之前,无须建立显式的连接;
- 分组可以在传输期间丢失,不保证数据的一定能够到达其目的地;
- 分组接收的次序不一定与发送的次序相同。
4、各协议层的数据划分为首部和数据
首部部分包含了与数据部分有关的元数据(目标地址、长度、传输协议类型等);
数据部分包含有用数据(或净荷)。
传输的基本单位是帧,网卡以帧为单位发送数据。帧首部部分的主要数据项是目标系统的硬件地址,这是数据传输的目的地,通过电缆传输数据时也需要该数据项。
高层协议的数据在封闭到以太网帧时,将协议产生的首部和数据元二组封装到帧的数据部分。
网络分层模型
内核网络子系统的实现与TCP/IP参考模型非常相似。相关的C语言代码划分为不同层次,各层次都有明确定义的任务,各个层次只能通过明确定义的接口与上下紧邻的层次通信。这种做法的好处在于,可以组合使用各种设备、传输机制和协议。
Linux 网络核心架构分为三层:用户空间的应用层,内核空间的网络协议栈层,物理硬件层。
其中最重要的核心是内核空间的协议格层。在整个栈按照严格分层设计思想可分为五层:系统调用接口层–>协议无关的接口层–>网络协议实现层–>驱动接口层–>驱动程序层。
ixgb 驱动:http://t.csdnimg.cn/HV15O
Linux 内核网络栈涉及3层,用 L2 L3 L4三层分别对应OSI(数据链路层 网络层 传输层)。
内核栈的任务就是将接收到的数据包从L2(网络设备驱动程序)传递给L3(网络层,通常为IPv4或IPv6),接下来,如果数据包目的地为当前设备,Linux 内核网络栈就将其传递给 L4(传输层,应用 TCP 或 UDP 协议侦听套接字)。如果数据包需要转发,就将其交给 L2 进行传输。有可能产生:数据包可能被丢失、可能需要重组数据包、需要计算数据包的检验和等等。
套接字缓冲区
在内核分析(收到)网络分组时,底层协议的数据将传递到更高的层。发送数据时顺序相反,各种协议产生的数据(首部和净荷)依次向更低的层传递,直至最终发送。这些操作的速度对网络子系统的性能有决定性的影响,因此内核使用一种特殊的结构,称为套接字缓冲区(socket buffer)。
Socket Buffer 主要由两部分组成。
1、数据包:存放了在网络中实际流通的数据。
2、管理数据结构(struct sk_buff):当在内核中对数据包进行时,内核还需要一些其他的数据来管理数据包和操作数据包,例如协议之间的交换信息,数据的状态,时间等。
Socket Buffer 有什么作用呢?
struct sk_buff 数据结构中存放了套接字接收 / 发送的数据。
在发送数据时,在套接字层创建了 Socket Buffer 缓冲区与管理数据结构,存放来自应用程序的数据。
在接收数据包时,Socket Buffer 则在网络设备的驱动程序中创建,存放来自网络的数据。
在发送和接受数据的过程中,各层协议的头信息会不断从数据包中插入和去掉,sk_buff
结构中描述协议头信息的地址指针也会被不断地赋值和复位。
一个网络数据包,它由双向链表构成,sk_buff
结构表示一个包含报头的入站或出站数据包在内核中 sk_buff
表示(SKB表示套接字缓冲区)。这个结构体并不直接存储网络数据包,而是存放了数据包的指针。
套接字缓冲区的基本思想是,通过操作指针来增删协议首部。
head
和 end
指向数据在内存中的起始和结束位置;
data
和 tail
指向协议数据区域的起始和结束位置;
mac_header
指向 MAC 协议首部的起始;
而 network_header
和 transport_header
分别指向网络层和传输层协议首部的起始。
在套接字缓冲区传递到互联网层时,必须增加一个新层。只需要向已经分配但尚未占用的那部分内存空间定稿的数据即可,除了 data
之外所有的指针都不变,data
现在指向 IP 首部的起始处。
对接收分组进行分析过程类似:分组数据复制到内核分配的一个内存区中,并在整个分析期间一直处于该内存区中。与该分组关联的套接字缓冲区在各层之间顺序传递。
如果是从 L4 传输到 L2,则是通过往sk_buff
结构体中增加该层协议头来操作;如果是从L4到L2,则是通过移动sk_buff
结构体中的data
指针来实现,不会删除各层协议头。 这样做可以提高CPU的工作效率!
net_device 网络设备
net_device
结构体存储着网络设备的所有信息,每个设备都有这种结构。所有设备的 net_device
结构放在一个全局变量dev_base
所有全局列表中。
和 sk_buff
一样,整体结构相当庞大的。结构体中有一个 next
指针,用来连接系统中所有网络设备。内核把这些连接起来的设备组成一个链表,并由全局变量 dev_base
指向链表的第一个元素。
struct net_device {/* 设备名称,如eth0 */char name[IFNAMSIZ];/* 名称hash */struct hlist_node name_hlist;char *ifalias;/** I/O specific fields* FIXME: Merge these and struct ifmap into one*//*描述设备所用的共享内存,用于设备与内核沟通其初始化和访问只会在设备驱动程序内进行*/unsigned long mem_end;unsigned long mem_start;/* 设备自有内存映射到I/O内存的起始地址 */unsigned long base_addr;/*设备与内核对话的中断编号,此值可由多个设备共享驱动程序使用request_irq函数分配此变量,使用free_irq予以释放*/int irq;/* 侦测网络状态的改变次数 */atomic_t carrier_changes;/** Some hardware also needs these fields (state,dev_list,* napi_list,unreg_list,close_list) but they are not* part of the usual set specified in Space.c.*//*网络队列子系统使用的一组标识由__LINK_STATE_xxx标识*/unsigned long state;struct list_head dev_list;struct list_head napi_list;struct list_head unreg_list;struct list_head close_list;/* 当前设备所有协议的链表 */struct list_head ptype_all;/* 当前设备特定协议的链表 */struct list_head ptype_specific;struct {struct list_head upper;struct list_head lower;} adj_list;/*用于存在其他一些设备功能可报告适配卡的功能,以便与CPU通信使用NETIF_F_XXX标识功能特性*/netdev_features_t features;netdev_features_t hw_features;netdev_features_t wanted_features;netdev_features_t vlan_features;netdev_features_t hw_enc_features;netdev_features_t mpls_features;netdev_features_t gso_partial_features;/* 网络设备索引号 */int ifindex;/* 设备组,默认都属于0组 */int group;struct net_device_stats stats;atomic_long_t rx_dropped;atomic_long_t tx_dropped;atomic_long_t rx_nohandler;#ifdef CONFIG_WIRELESS_EXTconst struct iw_handler_def *wireless_handlers;struct iw_public_data *wireless_data;
#endif/* 设备操作接口 */const struct net_device_ops *netdev_ops;/* ethtool操作接口 */const struct ethtool_ops *ethtool_ops;
#ifdef CONFIG_NET_SWITCHDEVconst struct switchdev_ops *switchdev_ops;
#endif
#ifdef CONFIG_NET_L3_MASTER_DEVconst struct l3mdev_ops *l3mdev_ops;
#endif
#if IS_ENABLED(CONFIG_IPV6)const struct ndisc_ops *ndisc_ops;
#endif#ifdef CONFIG_XFRMconst struct xfrmdev_ops *xfrmdev_ops;
#endif/* 头部一些操作,如链路层缓存,校验等 */const struct header_ops *header_ops;/* 标识接口特性,IFF_XXX,如IFF_UP */unsigned int flags;/*用于存储用户空间不可见的标识由VLAN和Bridge虚拟设备使用*/unsigned int priv_flags;/* 几乎不使用,为了兼容保留 */unsigned short gflags;/* 结构对齐填充 */unsigned short padded;/* 与interface group mib中的IfOperStatus相关 */unsigned char operstate;unsigned char link_mode;/*接口使用的端口类型*/unsigned char if_port;/*设备使用的DMA通道并非所有设备都可以用DMA,有些总线不支持DMA*/unsigned char dma;/*最大传输单元,标识设备能处理帧的最大尺寸Ethernet-1500*/unsigned int mtu;/* 最小mtu,Ethernet-68 */unsigned int min_mtu;/* 最大mut,Ethernet-65535 */unsigned int max_mtu;/* 设备所属类型ARP模块中,用type判断接口的硬件地址类型以太网接口为ARPHRD_ETHER*/unsigned short type;/*设备头部长度Ethernet报头是ETH_HLEN=14字节*/unsigned short hard_header_len;unsigned char min_header_len;/* 必须的头部空间 */unsigned short needed_headroom;unsigned short needed_tailroom;/* Interface address info. *//* 硬件地址,通常在初始化过程中从硬件读取 */unsigned char perm_addr[MAX_ADDR_LEN];unsigned char addr_assign_type;/* 硬件地址长度 */unsigned char addr_len;unsigned short neigh_priv_len;unsigned short dev_id;unsigned short dev_port;spinlock_t addr_list_lock;/* 设备名赋值类型,如NET_NAME_UNKNOWN */unsigned char name_assign_type;bool uc_promisc;struct netdev_hw_addr_list uc;struct netdev_hw_addr_list mc;struct netdev_hw_addr_list dev_addrs;#ifdef CONFIG_SYSFSstruct kset *queues_kset;
#endif/* 混杂模式开启数量 */unsigned int promiscuity;/* 非零值时,设备监听所有多播地址 */unsigned int allmulti;/* Protocol-specific pointers */
/* 特定协议的指针 */
#if IS_ENABLED(CONFIG_VLAN_8021Q)struct vlan_info __rcu *vlan_info;
#endif
#if IS_ENABLED(CONFIG_NET_DSA)struct dsa_switch_tree *dsa_ptr;
#endif
#if IS_ENABLED(CONFIG_TIPC)struct tipc_bearer __rcu *tipc_ptr;
#endifvoid *atalk_ptr;/* ip指向in_device结构 */struct in_device __rcu *ip_ptr;struct dn_dev __rcu *dn_ptr;struct inet6_dev __rcu *ip6_ptr;void *ax25_ptr;struct wireless_dev *ieee80211_ptr;struct wpan_dev *ieee802154_ptr;
#if IS_ENABLED(CONFIG_MPLS_ROUTING)struct mpls_dev __rcu *mpls_ptr;
#endif/** Cache lines mostly used on receive path (including eth_type_trans())*//* Interface address info used in eth_type_trans() */unsigned char *dev_addr;#ifdef CONFIG_SYSFS/* 接收队列 */struct netdev_rx_queue *_rx;/* 接收队列数 */unsigned int num_rx_queues;unsigned int real_num_rx_queues;
#endifstruct bpf_prog __rcu *xdp_prog;unsigned long gro_flush_timeout;/* 如网桥等的收包回调 */rx_handler_func_t __rcu *rx_handler;/* 回调参数 */void __rcu *rx_handler_data;#ifdef CONFIG_NET_CLS_ACTstruct tcf_proto __rcu *ingress_cl_list;
#endifstruct netdev_queue __rcu *ingress_queue;
#ifdef CONFIG_NETFILTER_INGRESS/* netfilter入口 */struct nf_hook_entry __rcu *nf_hooks_ingress;
#endif/* 链路层广播地址 */unsigned char broadcast[MAX_ADDR_LEN];
#ifdef CONFIG_RFS_ACCELstruct cpu_rmap *rx_cpu_rmap;
#endif/* 接口索引hash */struct hlist_node index_hlist;/** Cache lines mostly used on transmit path*//* 发送队列 */struct netdev_queue *_tx ____cacheline_aligned_in_smp;/* 发送队列数 */unsigned int num_tx_queues;unsigned int real_num_tx_queues;/* 排队规则 */struct Qdisc *qdisc;
#ifdef CONFIG_NET_SCHEDDECLARE_HASHTABLE (qdisc_hash, 4);
#endif/*可在设备发送队列中排队的最大数据包数*/unsigned long tx_queue_len;spinlock_t tx_global_lock;/* 网络层确定传输超时,调用驱动程序tx_timeout接口的最短时间*/int watchdog_timeo;#ifdef CONFIG_XPSstruct xps_dev_maps __rcu *xps_maps;
#endif
#ifdef CONFIG_NET_CLS_ACTstruct tcf_proto __rcu *egress_cl_list;
#endif/* These may be needed for future network-power-down code. *//* watchdog定时器 */struct timer_list watchdog_timer;/* 引用计数 */int __percpu *pcpu_refcnt;/* 网络设备的注册和除名以两步进行,该字段用于处理第二步*/struct list_head todo_list;struct list_head link_watch_list;/* 设备的注册状态 */enum { NETREG_UNINITIALIZED=0,NETREG_REGISTERED, /* completed register_netdevice */NETREG_UNREGISTERING, /* called unregister_netdevice */NETREG_UNREGISTERED, /* completed unregister todo */NETREG_RELEASED, /* called free_netdev */NETREG_DUMMY, /* dummy device for NAPI poll */} reg_state:8;/* 设备要被释放标记 */bool dismantle;enum {RTNL_LINK_INITIALIZED,RTNL_LINK_INITIALIZING,} rtnl_link_state:16;bool needs_free_netdev;void (*priv_destructor)(struct net_device *dev);#ifdef CONFIG_NETPOLLstruct netpoll_info __rcu *npinfo;
#endifpossible_net_t nd_net;/* mid-layer private */union {void *ml_priv;struct pcpu_lstats __percpu *lstats;struct pcpu_sw_netstats __percpu *tstats;struct pcpu_dstats __percpu *dstats;struct pcpu_vstats __percpu *vstats;};#if IS_ENABLED(CONFIG_GARP)struct garp_port __rcu *garp_port;
#endif
#if IS_ENABLED(CONFIG_MRP)struct mrp_port __rcu *mrp_port;
#endifstruct device dev;const struct attribute_group *sysfs_groups[4];const struct attribute_group *sysfs_rx_queue_group;const struct rtnl_link_ops *rtnl_link_ops;/* for setting kernel sock attribute on TCP connection setup */
#define GSO_MAX_SIZE 65536unsigned int gso_max_size;
#define GSO_MAX_SEGS 65535u16 gso_max_segs;#ifdef CONFIG_DCBconst struct dcbnl_rtnl_ops *dcbnl_ops;
#endifu8 num_tc;struct netdev_tc_txq tc_to_txq[TC_MAX_QUEUE];u8 prio_tc_map[TC_BITMASK + 1];#if IS_ENABLED(CONFIG_FCOE)unsigned int fcoe_ddp_xid;
#endif
#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)struct netprio_map __rcu *priomap;
#endifstruct phy_device *phydev;struct lock_class_key *qdisc_tx_busylock;struct lock_class_key *qdisc_running_key;bool proto_down;
};
网络设备接收数据的主要方法是由中断引发设备的中断处理函数,中断处理函数判断中断类型,如果为接收中断,则读取接收到的数据,分配 sk_buffer 数据结构和数据缓冲区,将接收到的数据复制到数据缓冲区,并调用 netif_rx()
函数将 sk_buffer 传递给上层协议。
网络设备中 NAP,老式网络设备驱动程序是在中断驱动模式下工作,意味着每接收一个数据包,就需要中断一次事实证明此工作方式在负载很高情况下效率降低,为此解决这个问题,开发一种新的软件技术–>NAPI(New API)。采用 NAPler 技术时,如果负载很高,网络设备驱动程序将在轮询模式,而不是中断驱动模式下运行。
【与数据包的中断接收方式不同的是,以轮询方式接收数据包时,当第一次中断发生后,中断处理程序要禁止设备的数据包接收中断并调度 NAPI】。
数据包的收发:网络设备驱动程序主要任务:接收目的地为当前主机的数据包,并将其传递给网络层,之后再将其传递给传输层。传输当前主机生成的外出数据包或转换当前主机收到数据包。对于每个数据包,无论它是接收到还是发送出去,都需要在路由子系统中执行一次查找操作。
每个 SKB(socket buffer) 都有一个dev成员(一个net_device
结构实例)对于到来的数据包,这个成员表示接收它的网络设备,而对于外出的数据包,这个成员表示发送它的网络设备。
https://www.cnblogs.com/theseventhson/p/15858194.html
https://www.cnblogs.com/whiteBear/p/16380625.html
网络设备之net_device结构与操作
相关文章:

Linux 内核源码分析---套接字
套接字通信 ISO 设计一种参考模型,定义组成网络的各个层,该模型由7层组成,称为OSI(开放 系统互连)模型如下: 应用层:网络服务与最终用户的接口; 表示层:数据的表示、安…...

vscode配置xdebug断点调试详细教程
注:环境为本地windows开发环境,编辑器为vscode,PHP集成环境工具为EServer vscode安装扩展并配置 安装PHP Debug 扩展中搜索 PHP Debug 并安装: 配置PHP Debug 1、点击扩展设置 2、在设置中,点击 setting.json 3、编…...

【人工智能】Transformers之Pipeline(八):文生图/图生图(text-to-image/image-to-image)
目录 一、引言 二、文生图/图生图(text-to-image/image-to-image) 2.1 文生图 2.2 图生图 2.3 技术原理 2.3.1 Diffusion扩散模型原理 2.3.2 Stable Diffusion扩散模型原理 2.4 文生图实战 2.4.1 SDXL 1.0 2.4.2 SD 2.0 2.5 模型排名 三、总…...

AI Agent 工程师认证-学习笔记(1)——【单Agent】ModelScope-Agent
学习链接: 【单Agent】ModelScope-Agent学习指南https://datawhaler.feishu.cn/wiki/GhOLwvAPkiSWmokjUgqc1eGonDf 手把手Agent开发开源教程(觉得不错的话可以star一下)https://github.com/datawhalechina/agent-tutorial 动手学Agent应用…...
【Python机器学习】树回归——将CART算法用于回归
要对数据的复杂关系建模,可以借用树结构来帮助切分数据,如何实现数据的切分?怎样才能知道是否已经充分切分?这些问题的答案取决于叶节点的建模方式。回归树假设叶节点是常数值,这种策略认为数据中的复杂关系可以用树结…...

前端(HTML + CSS)小兔鲜儿项目(仿)
前言 这是一个简单的商城网站,代码部分为HTML CSS 和少量JS代码 项目总览 一、头部区域 头部的 购物车 和 手机 用的是 文字图标,所以效果可以和文字一样 购物车右上角用的是绝对定位 logo用的是 h1 标签,用来提高网站搜索排名 二、banne…...
【Rust光年纪】构建高效终端用户界面:Rust库全面解析
构建优雅终端应用:深度评析六大Rust库 前言 随着Rust语言的流行和应用场景的不断扩大,对于终端操作和用户界面构建的需求也日益增长。本文将介绍一些在Rust语言中常用的终端操作库和用户界面构建库,以及它们的核心功能、使用场景、安装与配…...
鼠标滑动选中表格部分数据列(vue指令)
文章目录 代码指令代码使用代码 代码 指令代码 // 获得鼠标移动的范围 function getMoveRange(startClientX, endClientX, startClientY, endClientY) {const _startClientX Math.min(startClientX, endClientX);const _endClientX Math.max(startClientX, endClientX);con…...

“5G+Windows”推动全场景数字化升级:美格智能5G智能模组SRM930成功运行Windows 11系统
操作系统作为连接用户与数字世界的桥梁,在数字化迅速发展的时代扮演着至关重要的角色,智能设备与操作系统的协同工作,成为推动现代生活和商业效率的关键力量。其中,Windows系统以其广泛的应用基础和强大的兼容性成为全球最广泛使用…...

c语言学习,isupper()函数分析
1:isupper() 函数说明: 检查参数c,是否为大写英文字母。 2:函数原型: int isupper(int c) 3:函数参数: 参数c,为检测整数 4:返回值: 参数c是大写英文字母&…...

Adnroid 数据存储:SharedPreferences详解【SharedPreferencesUtils,SharedPreferences的ANR】
目录 1)SP是什么、如何使用,SPUtils 2)SP的流程 3)comit和apply 一、SP是什么,如何使用,SPUtils 1.1 SP是什么? SharedPreferences是Android平台提供的一种轻量级的数据存储方式,…...

Sentinel 规则持久化到 Nacos 实战
前言: 前面系列文章我们对 Sentinel 的作用及工作流程源码进行了分析,我们知道 Sentinel 的众多功能都是通过规则配置完成的,但是我们前面在演示的时候,发现 Sentinel 一重启,配置的规则就没有了,这是因为…...

服务器CPU天梯图2024年8月,含EYPC/至强及E3/E5
原文地址(高清无水印原图/持续更新/含榜单出处链接): >>>服务器CPU天梯图<<< 本文提供的服务器CPU天梯图数据均采集自各大专业网站,榜单图片末尾会标准其来源(挂太多链接有概率会被ban,…...

SpringBoot加载dll文件示例
1、将动态库放在resource文件目录下 2、编写相关加载逻辑 import lombok.extern.slf4j.Slf4j; import java.io.File; import java.io.IOException; import java.lang.reflect.Field; import java.util.HashMap;/*** Description: 加载动态库 .dll文件* author: Be.insighted* c…...

9.C基础_指针与数组
数组指针(一维数组) 数组指针就是" 数组的指针 ",它是一个指向数组首地址的指针变量。 1、数组名的含义 对于一维数组,数组名就是一个指针,指向数组的首地址。 基于如下代码进行分析: int a…...

C语言——结构体与共用体
C语言——结构体与共用体 结构体共用体 结构体 如果将复杂的复杂的数据类型组织成一个组合项,在一个组合项中包含若干个类型不同(当然也可以相同)的数据项。 C语言允许用户自己指定这样一种数据结构,它称为结构体。 结构体的语法…...

vs+qt项目转qt creator
1、转换方法 打开vs工程,右键项目,Qt->Create Base .pro File 后面默认OK 如果工程有include和lib路径需要配置,则转换后的工程,需要修改pro文件 2.修改pro文件 例如转换后的工程如下: 修改后 # ------------…...
微信小程序 checkbox 实现双向绑定以及特殊交互处理
wxml文件代码如下: <!--页面顶部 引入wxs文件--> <wxs module"tools" src"../../filter/tools.wxs"></wxs> ... <checkbox-group bindchange"checkboxChange"><label class"weui-cell weui-check__…...

我在高职教STM32——I2C通信之读写EEPROM(1)
大家好,我是老耿,高职青椒一枚,一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次,同行应该都懂的,老师在课堂上教学几乎是没什么成就感的。正是如此,才有了借助CSDN平台寻求认同感和成就感的想法。在这里,我准备陆续把自己花了很多心思设计的教学课件分…...

【ARM】应用ArmDS移植最小FreeRTOS系统
【更多软件使用问题请点击亿道电子官方网站】 一、文档背景 FreeRTOS(Free Real-Time Operating System)是一个开源的实时操作系统内核,广泛应用于嵌入式系统。它具有小巧、灵活、低功耗等特点,支持多任务调度、信号量、队列等实…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...