当前位置: 首页 > 科技观察

一篇文章为大家带来Lwip数据包管理

时间:2023-03-12 18:47:34 科技观察

1.1、pbuf结构LWIP是TCP/IP协议栈的具体实现,本质是对数据包的处理,LWIP中使用了一个叫做pbuf的结构体来管理数据包,LWIP源码中的pbuf.c和pbuf.h这两个文件是关于pbuf的,pbuf的结构如下:pbuf.h文件中是翻译后的版本structpbuf{structpbuf*next;//形成链接时list,指向下一个pbufvoid*payload;//指向数据缓冲区u16_ttot_len;//pbuf链表中所有pbuf的数据长度u16_tlen;//当前bpuf中的数据长度u8_ttype;//pbuf类型u8_tflags;//statusu16_tref;//used记录当前pbuf被引用的次数};1.2、tot_len下面说说tot_len的解释。大家最好能看懂英文的意思。说完中文,再回头看看英文。1.3、类型我们从这里看类型,但是用编译器跳过去,就是pbuf_type的类型有typedefenum{PBUF_RAM,//pbuf的数据存放在pbuf的结构旁边,数据是storedinramPBUF_ROM,//pbuf数据存储在rom,PBUF_REF,//pbuf数据存储在ram中,但与pbuf结构的位置无关PBUF_POOL//pbuf结构和它的数据存储在同一个内存中池}pbuf_type;分别说说这四种类型1.3.1、PBUF_RAMPBUF_RAM类型的pbuf空间是从LWIP的内存堆中获取的。该方法用于协议栈和应用程序中要发送的数据。pbuf的申请是在pbuf_alloc()中进行的。PBUF_RAM类型的申请代码如下:在pbuf.c文件中,pbuf_alloc函数看到mem_malloc()函数,知道从内存堆中申请内存的大小为:pbuf的大小+实际申请的大小sizeoffset是一个偏移量,这个偏移量是用来存放一些头部字段的,比如TCP包头,IP头等等。最终应用的PBUF_RAM类型的pbuf结构体就是下图的part1。pbuf结构的第2部分是偏移量部分。1.3.2、PBUF_POOLPBUF_POOL类型的pbuf空间是从LWIP的内存池中获取的,因为是从内存池申请的,所以该类型pbuf的分配时间极短。当网卡接收到数据包时,我们采用这种方式:在pbuf.c文件中,由于在内存池中应用了pbuf_alloc函数,所以必须有对应的POOL类型。LWIP初始化时,会自动创建两类pbuf相关的POOL:MEMP_PBUF和MEMP_PBUF_POOL(在memp_std.h中),其中MEMP_PBUF用于PBUF_REF和PBUF_ROM,MEMP_PBUF_POOL用于PBUF_POOL类型。事实上,应用程序发送和接收的数据量可能很大,但每次分配内存池类型的内存大小是固定的,因此可能需要多次分配。最终分配成功的PBUF_POOL类型pbuf如下图:注意上图中只有第一个pbuf有偏移量。这是因为它是一个数据包,所以只需要一个偏移量来存储数据包的信息,不需要其他的pbuf!这部分也体现在代码中,第一个pbufpayload和后面的pbufpayload1.3.3,PBUF_ROM和PBUF_REFPBUF_ROM以及PBUF_REF类型的pbuf空间也是从LWIP的内存池中获取的,分配方式相同。他们使用memoryPoolMEMP_PBUF,这两种申请的是pbuf结构的内存空间,不包括数据空间,分配过程如下:PBUF_ROM和PBUF_REF不为数据空间申请内存,那么他们的数据在哪里空间?一个数据空间可以用在内存的其他地方,区别在于PBUF_ROM的数据空间在ROM中,而PBUF_REF的数据空间在RAM中。这两种pbuf最终如下:1.3.4、多种pbuf混合使用实际数据包可能同时使用多种pbuf,如下图:02数据包申请和释放pbuf申请和释放通过函数pbuf_alloc()和pbuf_free()来完成,pbuf_alloc()函数和pbuf_free()函数原型如下:两个重要的参数:layer和type,layer决定了申请协议栈的哪一层,type决定了申请的pbuf类型,layer决定了pbuf中的offset,也就是Pbuf数据预留的headerspacearea,pbuf.h文件定义了一个枚举类型pbuf_layer来描述LWIP中的层,如下: