LWIP手记【A】arp高速缓冲区清零

本文探讨了LWIP环境下ARP缓存的具体管理方式,包括ARP缓存记录的生存周期、超时机制及如何处理不存在主机的ARP请求等问题。深入分析了LWIP中ARP表项的维护流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ARP高速缓存里面存放了最近的Internet地址到MAC地址之间的映射记录。高速缓存的每一项的生存时间一般是20分钟,起始时间从被创建时开始计算。LWIP里面的全局变量arp_talbe的结构体成员ctime就是记录这个时间的。这里注意,每一项都有一个生存时间,每一项都是单独计时的。另外注意,如果对一个不存在的主机发出arp请求,一般设置超时时间是3分钟。这个在LWIP里面似乎没有看到。

何时重设超时值?卷1的第4章说“”“HOST Requirements RFC表明即使表项正在使用时,超时值也应该启动,但是大多数从伯克利系统演变而来的系统没有这样做--它们每次都是在访问表项的时候重设超时值。”

那么LIWP是何时设置超时值得呢?

我们这里讨论屏蔽DUBUG的情况。如果设置//#define LWIP_DEBUG  那么在etharp_tmr里面会有这个函数etharp_free_entry内部有

#ifdef LWIP_DEBUG
  /* for debugging, clean out the complete entry */
  arp_table[i].ctime = 0;
  arp_table[i].netif = NULL;
  ip_addr_set_zero(&arp_table[i].ipaddr);
  arp_table[i].ethaddr = ethzero;
#endif /* LWIP_DEBUG */

所以下面讨论不定义DEBUG的情况。

首先是调用etharp_find_entry进行对应条目ctime清零,然后在函数etharp_update_arp_entry对MAC地址赋值且ctime又清零。

然后超时,然后MAC地址保持,ctime这个计数器也是保持的,就是保持240这个数值。(为什么240?因为240 * 5=20分钟。5是etharp_tmr这个函数的参数),然后把state变为empty。

然后下次在运行发送IP的时候,然后重复以前步骤(注意重复的过程中,后来的mac将以前的覆盖)。

### LwIP 缓冲区管理机制 LwIP 是一种轻量级 TCP/IP 协议栈,广泛应用于嵌入式设备中。为了实现高效的内存管理和数据包处理,LwIP 提供了一种灵活的缓冲区机制——`pbuf`(packet buffer),用于存储和传递网络数据。 #### 1. `pbuf` 的基本概念 `pbuf` 是 LwIP 中的核心结构之一,用来表示网络数据包及其元信息。它支持多种类型的内存分配策略以及分片化的数据存储方式[^1]。以下是关于 `pbuf` 的一些重要特性: - **分层设计**:`pbuf` 支持不同的层次模型(如链路层、网络层、传输层等),每层可以通过设置偏移量来预留头部空间。 - **分片化存储**:当单个数据包过大时,`pbuf` 可以被拆分为多个片段,形成一个链表结构,从而降低大块连续内存的需求压力[^4]。 #### 2. 内存分配方式 LwIP 使用两种主要的方式来进行 `pbuf` 的内存分配: - **内存池(Memory Pool)** - 特点:预先分配固定的内存块集合,适用于小尺寸的数据包。 - 优势:快速分配与释放资源,有效减少内存碎片化问题[^1]。 - 局限性:由于内存池大小有限,可能导致无法满足超大数据包的需求。 - **动态堆分配(Heap Allocation)** - 动态从系统的自由内存中请求所需的空间,适合于较大或者不确定长度的数据包。 - 函数示例: ```c struct pbuf *p = pbuf_alloc(PBUF_POOL, size, PBUF_RAM); ``` #### 3. 数据复制行为分析 尽管 LwIP 致力于最小化不必要的数据拷贝操作,但在某些场景下仍然不可避免地发生数据移动。例如,在通过 socket 接口发送或接收数据的过程中,存在如下情况: - 发送方向上,应用程序提供的数据会被复制到由 `pbuf` 管理的内存区域中;随后各协议层依次附加相应的头文件并调整指针位置[^3]。 - 接收过程中,则是从底层驱动程序接收到原始帧后逐步剥离各个层级的头部直至最终交付给用户进程。 具体而言,涉及的关键函数包括但不限于以下几个方面: - `tcp_write()` —— 负责将应用层提交的信息写入到新创建出来的传输层对应的缓存单元里; - `TCP_DATA_COPY2()` —— 实现实际字节级别的迁移动作; - `pbuf_coalesce()` —— 合并现有的分散式的缓冲链条成为单一实体以便进一步优化性能表现[^2]. ```c // 示例代码展示如何手动构建一个新的组合型pbuf对象 struct pbuf* coalesced_pbuf = pbuf_coalesce(original_chain, PBUF_LINK); if (!coalesced_pbuf){ // 处理错误情形... } else{ process_data(coalesced_pbuf->payload, coalesced_pbuf->len); pbuf_free(coalesced_pbuf); } ``` 以上流程清晰表明了即使是在高度抽象后的API层面之下也隐藏着复杂的内部细节逻辑。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值