LWIP的IP 协议栈

IP 协议栈

下面的分析把上文对 IPv4 概念的说明与 lwIP 中的具体实现代码对应起来,便于将理论与实现对照理解。分析覆盖:输入处理、路由与转发、输出与报文构建、分片/重组、校验和与各种配置点(hook、选项、统计等)。


目录(快速导航)

  • ip4_input:接收与分发流程
  • ip4_route / ip4_forward:路由与转发决策
  • ip4_output_if / ip4_output:报文构建与发送
  • 校验和(inet_chksum、CHECKSUM_GEN_IP_INLINE)
  • 分片(ip4_frag)与重组(ip4_reass)
  • 辅助逻辑:广播/组播、DHCP 链路层地址接收、HOOKs、统计计数器

1. 接收流程(ip4_input)

对应代码函数:ip4_input(struct pbuf *p, struct netif *inp)

主要步骤:

  • 基本验证:
    • 检查版本 IPH_V(iphdr) == 4,否则丢弃(并记录错误)。
    • 计算首部长度 iphdr_hlen = IPH_HL_BYTES(iphdr),总长度 iphdr_len = lwip_ntohs(IPH_LEN(iphdr)),并用 pbuf_realloc/检查 p->tot_len,防止长度不一致。
  • 校验和:
    • 在 CHECKSUM_CHECK_IP 启用且 netif 支持时,调用 inet_chksum(iphdr, iphdr_hlen) 检查 IP 首部。
  • 地址拷贝与 netif 匹配:
    • 将 src/dest 拷贝到 ip_data.current_iphdr_*,调用 ip4_input_accept() 判断本接口是否接受(检查网卡是否 up、是否和本机 IP 匹配、广播/回环等)。
    • 对组播,若启用 IGMP,会查 igmp_lookfor_group() 决定是否接受。
    • 若 netif==NULL,且 IP_ACCEPT_LINK_LAYER_ADDRESSING 条件下,若目标为 DHCP 客户端端口,也会接受(允许链路层寻址的 DHCP 报文)。
  • 源地址合法性检查:
    • 拒绝源地址为广播或组播的包(RFC 1122 要求)。
  • 非本机包处理:
    • 如果 netif == NULL(不是给本机),在启用 IP_FORWARD 时调用 ip4_forward(),否则丢弃。
  • 分片处理:
    • 检测 IP_MF 或偏移不为 0,即是分片,调用 ip4_reass()(若启用 IP_REASSEMBLY)进行重组;若不启用,直接丢弃。
  • IP 选项:
    • 若 IP_OPTIONS_ALLOWED == 0 且存在选项(除 IGMP router-alert 的特殊允许),则丢弃。
  • 分发到传输层:
    • pbuf_remove_header(p, iphdr_hlen) 将 payload 调到传输层头部。
    • 根据 IP_PROTO 调用 udp_input/tcp_input/icmp_input/igmp_input 或 raw_input/返回 ICMP 不可达。
  • 清理与统计:
    • 使用 IP_STATS/MIB2 增加相应统计。

要点:

  • lwIP 在 ip 层只检查 IP 首部检验和(传输层有自己的校验),并在每个路由器处重新计算首部校验和(因为 TTL 会被减 1)。
  • pbuf 是 lwIP 的缓冲结构,ip4_input 会对 pbuf 做裁剪(pbuf_realloc)和头部移动(pbuf_remove_header)。
    在这里插入图片描述
    ip数据报格式。

在这里插入图片描述


2. 路由与转发(ip4_route / ip4_forward)

  • ip4_route(const ip4_addr_t *dest)
    • 线性遍历 netif 列表,检查 netif 是否 up、link up 且有地址;用 ip4_addr_netcmp 与 netmask 比较判断是否同网段。
    • 对多播有 ip4_default_multicast_netif 的支持(LWIP_MULTICAST_TX_OPTIONS)。
    • 若没有找到合适的 netif,会尝试 netif_default(并记录 rterr)。
  • ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
    • 首先用 ip4_canforward() 检查地址是否允许转发(不转发广播、多播、实验地址、回环等)。
    • 禁止转发链路本地地址(RFC3927)。
    • 查找下一跳 netif = ip4_route_src(src, dest)(可能有源地址路由 hook)。
    • 防止在输入 netif 上再次发出(可由 IP_FORWARD_ALLOW_TX_ON_RX_NETIF 控制)。
    • TTL–,若变为 0 则丢弃并发送 ICMP Time Exceeded(不对 ICMP 报文回复 ICMP)。
    • 增量更新首部校验和(不必完全重算)。
    • 处理分片:若 p->tot_len > netif->mtu:
      • 若允许分片(DF 未置位)且 IP_FRAG 启用,则调用 ip4_frag()。
      • 否则发送 ICMP Destination Unreachable (Fragmentation Needed)。
    • 最后调用 netif->output(netif, p, dest) 将数据放到链路层。

要点:

  • 转发功能可选(IP_FORWARD 宏)。嵌入式通常按需启用。
  • 增量校验和更新是性能优化(仅因为 TTL 字段改变)。

3. 发送与报文构建(ip4_output_if / ip4_output)

对应函数:ip4_output_if_src / ip4_output_if / ip4_output

主要流程:

  • ip4_output():高层入口,先通过 ip4_route_src 找到合适 netif,然后调用 ip4_output_if()。
  • ip4_output_if():判断是否需要生成 IP 首部(dest != LWIP_IP_HDRINCL)。
    • 若需要生成:
      • 可能插入 IP 选项(IP_OPTIONS_SEND),并把 pbuf 前面扩展出选项区与 IP_HLEN(pbuf_add_header)。
      • 填写 IP 字段:版本、头长、TOS、长度(p->tot_len)、标识(ip_id++)、偏移(0)、TTL、协议、源/目的地址。
      • 计算并填写首部校验和(支持 inline 计算或 inet_chksum,受 CHECKSUM_GEN_IP_INLINE、CHECKSUM_GEN_IP、NETIF_CHECKSUM_GEN_IP 控制)。
    • 若 dest == LWIP_IP_HDRINCL:p 已包含 IP 头,直接使用 p->payload。
  • 回环与多播处理:
    • 若目标是本机地址或 loopback,则调用 netif_loop_output。
    • 若 IP_FRAG 启用且 p->tot_len > netif->mtu,则调用 ip4_frag() 分片发送。
  • 最后调用 netif->output(netif, p, dest)。

要点:

  • ip_id 是静态全局 u16_t,用于 IP 标识字段(RFC791 建议各实现可自有策略)。
  • LWIP 支持用户提前构造 IP 头(LWIP_IP_HDRINCL),或由栈自动构建。
  • netif->output 负责把 IP 包封装到链路层(通常最终会调用 etharp_output 或底层驱动)。

4. 校验和实现细节

  • IP 首部校验和:
    • 接收时:CHECKSUM_CHECK_IP 宏控制是否在 netif 启用硬件/软件校验时检查;使用 inet_chksum(iphdr, iphdr_hlen)。
    • 发送时:CHECKSUM_GEN_IP 或 CHECKSUM_GEN_IP_INLINE 控制是否内联计算校验和或调用 inet_chksum。
    • LWIP_CHECKSUM_CTRL_PER_NETIF 允许 per-netif 配置是否生成/检查校验和。
  • 传输层校验和(TCP/UDP)由各层自己计算/检查。

要点:

  • 每次路由器处理需要修改 TTL,会相应更新首部校验和(代码用增量方式更新,避免重算)。

5. 分片(ip4_frag)与重组(ip4_reass)

分片发送:ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)

  • 只在发送端且 netif->mtu 小于 p->tot_len 时触发(并受 IP_FRAG 宏控制)。
  • 要点:
    • 不支持 IP options(IPH_HL_BYTES 必须等于 IP_HLEN)。
    • 以 8 字节为单位分片(nfb = (mtu - IP_HLEN)/8)。
    • 使用 pbuf_alloc / pbuf_alloced_custom 等机制,创建每个片的 pbuf 链(有的配置使用 PBUF_REF 避免复制)。
    • 每个片设置偏移量(IP_OFFMASK + IP_MF),设置长度、首部校验和,并调用 netif->output 发送。
    • 若内存不足返回 ERR_MEM。

分片重组:ip4_reass(struct pbuf *p)

  • 仅在 IP_REASSEMBLY 启用时存在。
  • 使用 struct ip_reassdata 链表保存正在重组的报文,每个报文链由多个 pbuf(头部被替换为 ip_reass_helper 结构)串联。
  • 关键点:
    • ip_reass_enqueue_new_datagram:为新报文分配 ip_reassdata。
    • ip_reass_chain_frag_into_datagram_and_validate:插入并检测重叠、缺片、排序;计算是否已全部接收。
    • ip_reass_pbufcount 控制系统内排队 pbuf 总量(避免资源耗尽)。
    • 超时机制 ip_reass_tmr(每 IP_TMR_INTERVAL 调用一次,过期则清理并可能发送 ICMP Time Exceeded)。
    • 成功重组时把 pbuf 链拼接、恢复 IP 头并返回完整 pbuf。

要点:

  • 重组在接收端进行(端系统处理),路由器不重组。

  • 若发生重叠或资源不足,会丢弃分片/报文并统计相应错误。

  • 支持策略:IP_REASS_FREE_OLDEST 在队满时释放最旧报文以给新报文空间。
    在这里插入图片描述

  • 何时发生分片

    • 当要发送的 IP 数据报(包括 IP 首部)比下一跳链路的 MTU 大时,源主机或转发主机必须将数据报分片以适应 MTU。
    • 如果 IP 头部的 DF(Don’t Fragment)位被置位,则不能分片,若超过 MTU 则应产生 ICMP Destination Unreachable(Fragmentation Needed)。
  • 分片的单位与偏移量

    • IPv4 分片偏移量(Fragment Offset)单位是 8 字节(64 位)。因此,除首/尾片外每个分片的数据长度必须是8的整数倍(除非是最后一个分片)。
    • lwIP 中计算每片数据块数: nfb = (netif->mtu - IP_HLEN) / 8;实际每片数据字节数 = nfb * 8。
  • 发送端(ip4_frag)的关键步骤(对应源码要点)

    • 不支持带 IP option 的数据报(在 lwIP ip4_frag 中要求 IPH_HL_BYTES == IP_HLEN)。
    • 计算要分的片数并循环:
      • 为每片准备 pbuf:在不同配置下使用 PBUF_RAM(复制数据)或用 PBUF_REF / pbuf_alloced_custom 来引用原始 pbuf 的数据以避免拷贝(节省内存/CPU)。
      • 设置每片的 IP 首部字段:
        • 将原始首部复制到每个片的首部位置(除某些字段外保持一致)。
        • 设置长度(片的总长度 = IP_HLEN + 片数据长度)。
        • 计算并设置分片偏移量(以 8 字节为单位)和 MF(更多片)位:除最后一片外 MF=1,最后一片 MF=0。
        • 计算 IP 首部校验和(受 CHECKSUM_GEN_IP / CHECKSUM_GEN_IP_INLINE / NETIF_CHECKSUM_GEN_IP 控制)。
      • 调用 netif->output(netif, rambuf, dest) 逐片发送,然后释放 rambuf(注意硬件可能异步使用)。
    • 返回 ERR_OK 或在内存不足时返回 ERR_MEM。
  • 接收端重组(ip4_reass)的关键步骤(对应源码要点)

    • 入口:当接收到分片(IPH_OFFSET 中含有 MF 或 offset != 0)时,ip4_input 调用 ip4_reass。
    • 结构与队列:
      • 用 struct ip_reassdata 链表保存待重组的报文(每个 ip_reassdata 保留原始第一个片的 IP 头副本、timer、pbuf 链等)。
      • 为每个已接片在 pbuf 的 IP 首部处放置一个小的 helper 结构(ip_reass_helper),记录该片在整体报文中的 start/end 偏移以及指向下一个片的指针。
    • 入队与插入验证(ip_reass_chain_frag_into_datagram_and_validate):
      • 将新片按 start 偏移排序插入链表(在正确位置插入或追加)。
      • 检查重叠(可选,受 IP_REASS_CHECK_OVERLAP 控制):若重叠或重复片可选择丢弃。
      • 检查“洞”(missing fragments):若链中有间隙则标记为未完成(valid = 0)。
      • 若见到最后一片(MF==0),并且链上没有洞,则认为重组已完成。
    • 资源与防护
      • 使用 ip_reass_pbufcount 跟踪已占用 pbuf 数量,并限制最大排队 pbuf(IP_REASS_MAX_PBUFS)。
      • 当达到上限时,可通过 IP_REASS_FREE_OLDEST 策略释放最旧报文以腾出空间(实现中有此可选行为)。
      • 超时机制:ip_reass_tmr 每 IP_TMR_INTERVAL(一般 1s)递减重组项 timer,超时后释放并(如果已接到第一个片)发送 ICMP Time Exceeded。
    • 成功重组
      • 将所有片的 pbuf 链按顺序拼接:对于除第一片外每个片调用 pbuf_remove_header(r, IP_HLEN) 隐藏其 IP 首部,然后用 pbuf_cat 把它们追加到第一个 pbuf。
      • 恢复第一个 pbuf 的原始 IP 首部(从 ipr->iphdr 拷贝),设置总长度、将偏移设为 0,校验和重算(若需要)。
      • 从重组队列中移除并释放 ip_reassdata,更新 ip_reass_pbufcount,返回完整的 pbuf 链给上层处理。
    • 失败情形
      • 如果出现重叠(并被配置为拒绝)、内存不足、或超时,丢弃分片并相应更新统计;在某些情形会发送 ICMP(例如超时发送 Time Exceeded,或 DF 导致分片失败则转发端会触发 ICMP)。
  • 路由器与终端的区别

    • 路由器不应(且在 lwIP 默认实现中不)对通过它的分片进行重组:重组工作放在目的主机(端系统)上。路由器只转发分片(除非路由器自身就是目的主机)。
    • 因此分片可以在路径上的不同链路被再次分片(分片的再分片),最终端系统负责按偏移装配回原始数据报。
  • 安全与性能注意事项

    • 分片可被滥用用于逃避检测或触发 DoS(大量未完成的重组会耗尽内存)。建议:
      • 限制 IP_REASS_MAX_PBUFS(或直接禁用 IP_REASSEMBLY,当能保证上层不依赖分片时)。
      • 启用 IP_REASS_FREE_OLDEST 或短重组超时以减少资源占用窗口。
      • 严格处理重叠片(拒绝或按策略合并)。
    • 分片/重组会增加延迟并消耗内存与 CPU,能避免时尽量通过 Path MTU Discovery(PMTUD)或尽量发送小包减少分片需求。
  • 示例

    • 原始 IP 数据段:3980 字节(不含 20 字节 IP 头),通过 MTU=1500 的链路。
    • 每片能承载的数据 = 1500 - 20 = 1480 字节(且为8字节倍数)。
    • 分片方案:
      • 分片 1:数据长度 1480,偏移 0,MF = 1,总长 1500(含 20 字节头)。
      • 分片 2:数据长度 1480,偏移 1480/8 = 185,MF = 1,总长 1500。
      • 分片 3(最后片):数据长度 = 3980 - 1480 - 1480 = 1020,偏移 = 185 + 185 = 370,MF = 0,总长 = 1020 + 20 = 1040。
    • 目的主机收到三片后根据偏移(0, 185, 370)拼接成完整 3980 字节数据并交给传输层。
  • 实践建议(对 lwIP 配置)

    • 如果内存充足且需要接收任意分片:启用 IP_REASSEMBLY,合理增大 IP_REASS_MAX_PBUFS 并启用 IP_REASS_FREE_OLDEST(以减轻洪泛)。
    • 对于路由器/网关:通常关闭重组(路由器不必重组)并启用转发(IP_FORWARD),确保 DF/MTU/ICMP Path MTU 策略正确。
    • 若链路 MTU 可变或紧张:优先使用 PMTUD 或在上层限制 MSS/MTU,减少 IP 分片发生。

(上述流程直接映射至 lwIP 源码中的 ip4_frag、ip4_reass、ip_reass_tmr、ip_reass_chain_frag_into_datagram_and_validate、ip4_input 等函数)


6. 组播、广播与 DHCP(链路层寻址)

  • 代码中对组播做了专门处理:
    • ip4_input 在 dest 为 multicast 时会对 IGMP 做额外检查(igmp_lookfor_group)。
    • ip4_route 支持 ip4_default_multicast_netif(LWIP_MULTICAST_TX_OPTIONS)。
  • 将链路层寻址包(例如 DHCP Server->Client reply)在 netif down 时仍能接收:
    • IP_ACCEPT_LINK_LAYER_ADDRESSING 宏及 IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT 的扩展允许接受目的 IP 不匹配的 UDP 包(通常用于 DHCP)。
    • 当 netif==NULL 并检测到 UDP 且目标端口为 DHCP 客户端端口时,强制接受。

7. Hook 与可配置项(可扩展点)

代码中暴露多个 hook / macro 以便定制:

  • LWIP_HOOK_IP4_INPUT:在 ip4_input 开始时可「吃掉」包(返回非 0 则视为已处理)。
  • LWIP_HOOK_IP4_ROUTE_SRC / LWIP_HOOK_IP4_ROUTE:可自定义路由选择(包括基于源地址的路由)。
  • LWIP_HOOK_IP4_CANFORWARD:自定义能否转发判断。
  • LWIP_NETIF_LOOPBACK / NETIF_FLAG_BROADCAST / NETIF_CHECKSUM_* 等编译时选项影响行为。

8. 统计与调试

  • 大量 IP_STATS_*、MIB2_STATS_INC 用于统计收发、错误、转发、碎片、重组等信息,便于监控与调试。
  • IP_DEBUG / IP_REASS_DEBUG 等宏用于运行时打印调试信息(lwIP 的 LWIP_DEBUGF)。

9. 关联要点汇总

  • IP 地址与路由选择:理论上 IP 地址指定主机身份;实现上由 ip4_route() 根据 netif 和 netmask 找到发送接口。
  • TTL 防止循环:在 ip4_forward 中 TTL 每跳减 1,TTL 归 0 时发 ICMP 超时(icmp_time_exceeded)。
  • 分片单位与重组:
    • 理论:分片以 8 字节为单位;实现:nfb = (mtu - IP_HLEN) / 8,偏移以 8 字节单位设置。
    • 重组仅在接收端完成:ip4_reass 使用链表与 helper 结构保存片段。
  • NAT:用户文中描述 NAT 工作方式(修改源 IP:port 并维护转换表)属于应用/路由器层,lwIP core 没有内置完整 NAT 实现,这种功能通常由路由器软件/OS 层实现(lwIP 可以作为设备上的 IP 层基础)。
  • 校验和策略:IP 首部在每跳必须验证,发包时根据配置选择内联或函数计算;传输层还会做更广泛的校验(TCP/UDP 校验和)。
    在这里插入图片描述

10. 常见调整建议

  • 若设备作路由器:打开 IP_FORWARD、IP_FRAG、IP_REASSEMBLY;注意内存(IP_REASS_MAX_PBUFS)与安全(不要盲目接受链路层包)。
  • 若网卡有硬件校验:启用 LWIP_CHECKSUM_CTRL_PER_NETIF 并为 netif 配置 NETIF_CHECKSUM_*,可节约 CPU。
  • 对内存敏感:禁用 IP_REASSEMBLY 或启用 IP_REASS_FREE_OLDEST,慎重设置 IP_REASS_MAX_PBUFS。
  • 若需要高性能:启用 CHECKSUM_GEN_IP_INLINE,避免重复拷贝(使用 PBUF_REF / custom pbufs)。

11. 参考源码位置

  • 输入/输出主入口:ip4_input、ip4_output、ip4_output_if、ip4_output_if_src
  • 转发/路由:ip4_route、ip4_forward、ip4_canforward
  • 分片/重组:ip4_frag、ip4_reass、ip_reass_tmr、ip_reass_chain_frag_into_datagram_and_validate
  • 辅助:ip4_addr_isbroadcast_u32、ip4addr_aton、ip4addr_ntoa_r 等地址工具

12. 小结

将理论与lwIP实现对照可以看出:IP 协议栈在嵌入式实现中需要在功能完备与资源受限之间做折中。lwIP 提供了丰富的编译时配置点(碎片、重组、校验和、路由 hook 等),可以根据设备角色(终端/路由器/网关)调整。理解 ip4_input/ip4_output/ip4_frag/ip4_reass 这几个核心函数,能帮助定位大多数网络问题(丢包、碎片、路由错误、校验失败、DHCP/组播交互等)。

在这里插入图片描述
核心思路:验证 → 匹配本机/多播/广播 → 是否需转发 → 是否为分片 → 重组或直接分发到上层协议(UDP/TCP/ICMP/IGMP)或丢弃/回复 ICMP。

  • 关键处理步骤(按图自下而上)

    1. ethernet_input() 把以太网帧交给 ip4_input()(若是 IPv4)。
      关联源码:ethernet_input、netif 层。
    2. ip4_input() 首部验证(版本、首部长度、校验和、总长度)和源/目的地址基本检查。
      失败:丢弃并更新统计/可能发送 ICMP。
    3. 判断是否 IPv4(图中 “IPv4?”)。不是则由上层其它处理或丢弃。
    4. 检查目的地址是否为本机(ip4_addr_isloopback / 本机 IP / 多播 / 广播)。
      • 是本机:继续处理(进入分片重组或上层协议)。
      • 否且 netif==NULL:不是给本机——进入转发逻辑或丢弃(取决于 IP_FORWARD)。
    5. netif==NULL 分支:对于非广播/多播目标且启用转发,调用 ip4_forward() 转发;对广播通常不转发(直接丢弃或本地处理视实现)。
    6. 分片检测:若 IP 标志或偏移表明为分片(MF 或 offset!=0),调用 ip4_reass() 做重组。
      • 重组成功:交给上层协议处理。
      • 重组失败或超时:释放并可能发送 ICMP(Time Exceeded 等)。
    7. 分发到上层:根据 IP 协议字段发到 udp_input、tcp_input、icmp_input、igmp_input 或 raw_input;未知协议通常丢弃或统计错误。
  • 特别注意点

    • 分片在目的端重组:路由器不重组(转发即可),重组逻辑在 ip4_reass。
    • 多播与 IGMP:多播包可能需要额外的 IGMP 检查(igmp_lookfor_group)。
    • 广播处理:通常不转发到其它网段;交给本机所有接口的广播机制或丢弃。
    • netif==NULL 表示该包在本机没有匹配的接口(即目标不是本机地址),需要考虑是否转发。
    • 未知上层协议会被丢弃(或由 raw/pcap/probe 钩子捕获)。
  • 常见后续动作(实现/调试相关)

    • 出错会更新 IP_STATS/MIB2 并在启用的情况下打印调试信息。
    • 转发时若需分片且 DF=1,会触发 ICMP Destination Unreachable (Fragmentation Needed)。
    • 重组资源受限会导致丢弃,应检查 IP_REASS_MAX_PBUFS、重组超时策略等。
  • 源码映射(快速索引)

    • 入口/验证/分发:ip4_input
    • 重组:ip4_reass、ip_reass_tmr
    • 转发/路由:ip4_forward、ip4_route、ip4_canforward
    • 发送到上层:udp_input / tcp_input / icmp_input / igmp_input

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

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

相关文章

高并发短信网关平台建设方案概述

本方案涵盖了架构设计、技术选型、核心功能、高可用保障以及实施路径,旨在构建一个能够应对千万级日吞吐量、稳定、安全、可扩展的现代短信网关平台。 高并发短信网关平台建设方案 一、 项目概述与目标 1.1 项目背景 为满足公司业务(如用户注册、登录、交易验证、营销通知…

阿里云服务-开启对象存储服务及获取AccessKey教程

(1)阿里云OSS简介 (2)打开阿里云网址:阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台 点击“立即开通” (2)开通成功后,充值任意金额 顶栏选择“费用”|“充值…

[特殊字符] 高可用高并发微服务架构设计:Nginx 与 API Gateway 的协同实践

一、Nginx 和 Gateway 的关系:是替代还是协作? 不是替代关系,而是协作关系。 1. Nginx 的角色(通常在最外层) 反向代理 & 负载均衡:将前端请求分发到多个后端服务或网关实例。 静态资源服务&#xf…

解码LLM量化:深入剖析最常见8位与4位核心算法

解码LLM量化:深入剖析8位与4位核心算法 大型语言模型(LLM)的性能日益强大,但其庞大的体积和高昂的计算成本构成了部署的主要障碍。模型量化,作为一种将高精度浮点权重(如16位)映射到低位宽整数&…

提问:温度不改变 logits 与概率的排名,为何还会影响模型输出?

你此前围绕温度的核心困惑始终是:“温度不改变 logits 与概率的排名,为何还会影响模型输出?” 以下总结将紧扣这一困惑,并重点补充核采样(Top-p)在其中的作用,明确温度与核采样如何共同影响输出…

【文献阅读】Lossless data compression by large models

1. 中华人工智能研究中心,郑州。 2. 鹏程实验室,深圳。 3. 上海数学与交叉学科研究所,上海。 4. 中国科学院计算技术研究所,北京。 5. 宁波人工智能产业研究所,宁波。 6. 滑铁卢大学计算机科学学院,加拿大安…

注意力机制:捕获长距离依赖关系的革命性技术

本文由「大千AI助手」原创发布,专注用真话讲AI,回归技术本质。拒绝神话或妖魔化。搜索「大千AI助手」关注我,一起撕掉过度包装,学习真实的AI技术! ✨ 1. 注意力机制概述:为什么需要关注"长距离依赖&qu…

PHP如何使用JpGraph生成柱形图?

PHP使用JpGraph库生成各类统计图形具有显著优势,该库作为专业的PHP图表生成工具,能够高效创建包括折线图、饼图、散点图在内的多种数据可视化图形,其核心价值在于提供了丰富的图形定制能力和简洁的API接口。JpGraph通过纯PHP实现,…

免费的端口映射工具 ChmlFrp

免费的端口映射工具 ChmlFrp 前言:之前我写过一篇关于cloudflare tunnel的使用教程,ChmlFrp是一个类似的工具,也可以用来进行内网穿透 我的博客对应文章地址 1.注册账号 注册地址 点击这个链接前往官网注册一个账号,过程简单&…

遥感领域解决方案丨涵盖:高光谱、无人机多光谱、空天地数据识别与计算

一:AI智慧高光谱遥感实战:手撕99个案例项目、全覆盖技术链与应用场景一站式提升方案在遥感技术飞速发展的今天,高光谱数据以其独特的光谱分辨率成为环境监测、精准农业、地质勘探等领域的核心数据源。然而,海量的波段数据、复杂的…

中科米堆CASAIM自动化三维测量设备测量汽车壳体直径尺寸

随着新能源汽车产业向轻量化与高集成度发展,壳体作为电池组和电驱系统的核心承载部件,其孔位加工精度直接影响装配密封性及结构强度,传统人工测量方式已难以满足现代化生产需求。自动化三维测量设备的引入,为汽车壳体直径尺寸测量…

08.21总结

圆方树 引入 我们注意到,树结构相比普通图具有诸多优良特性。若能将在无向图上求解的问题转化为树结构问题,往往能大幅简化求解过程。圆方树正是实现这一转化的有效工具。 定义 我们称原图中的点为"圆点"。通过引入方点并调整边的关系&#xf…

亚马逊广告优化新逻辑:从人工苦力到AI智能的进化之路

"为什么我的广告花费越来越高,转化却越来越差?""如何在海量关键词中找到真正能带来转化的黄金词?""为什么手动调整出价总是跟不上流量变化的速度?""怎样才能避免因库存问题导致的广告权重暴跌…

【51单片机】【protues仿真】基于51单片机水位监测系统

目录 一、主要功能 二、使用步骤 三、硬件资源 四、软件设计 五、实验现象 一、主要功能 1、数码管显示当前水位值 2、按键设置水位上下限阈值 3、当水位低于下限,启动蜂鸣器警报并抽水至水位上限停止抽水 4、电机模拟水泵,蜂鸣器,指示…

白名单过滤的文件上传如何bypass:boot2root靶机之fristileaks

靶机提示 base64解码提取图片 文件上传之apache多后缀名解析漏洞 linpeas dirtycow提权 靶机下载 通过网盘分享的文件:FristiLeaks_1.3.ova 链接: https://pan.baidu.com/s/1ZWznp8egNGwnQqwh1gkSZg?pwdwwvp 提取码: wwvp --来自百度网盘超级会员v8的分享主…

Centos 8 管理防火墙

firewall-cmd 检查与安装 在 CentOS 8 上安装和启用 firewalld(提供 firewall-cmd 工具)的步骤如下:1. 检查 **firewalld** 是否已安装 在安装前,先检查系统中是否已安装: sudo firewall-cmd --version如果返回版本号&…

使用PPT进行科研绘图过程中常用的快捷键

PPT科研绘图常用快捷键速查表功能类别快捷键功能描述基础操作与选择Ctrl A全选幻灯片上的所有对象。Ctrl D快速复制选中的对象,并自动保持等间距排列。Shift Click多选多个对象。Ctrl G将选中的多个对象组合成一个整体。Ctrl Shift G取消组合。Ctrl 拖动复制…

`strchr` 字符串查找函数

1) 函数的概念与用途 strchr 是 C 标准库中的一个基础但极其重要的字符串处理函数,它的名字来源于"string chracter"(字符串字符)。这个函数的功能非常明确:在字符串中查找特定字符的第一次出现位置。 可以将 strchr 想…

Redis 678

Redis 8 是当前的最新稳定版(截至 2024 年中),它在 Redis 7 的基础上带来了更多重要改进。我们来对这三个主要版本进行一次全面的功能和性能对比。 核心演进脉络 Redis 6 (2020):多线程时代的开创者。解决了网络 I/O 瓶颈&#xf…

【大白话解析】 OpenZeppelin 的 Address 库:Solidity安全地址交互工具箱​(附源代码)

🧩 一、这个文件是干嘛的?—— Address.sol 是个“工具箱” 你可以把这个 Address.sol文件理解为一个 ​​“工具箱”​​,里面装了一堆​​专门用来安全地跟别的地址(账户或合约)打交道的工具函数​​。 在区块链世界里,地址(address)可以是: ​​外部账户(EOA)…