LWIP中NETCONN接口编程(上)

本文介绍了LWIP中的netbuf结构体,它是pbuf的封装,用于管理应用线程的数据缓冲区。netbuf包含IP地址和端口号信息,通过netbuf_next()和netbuf_first()函数操作数据。LWIP提供了netbuf_new(), netbuf_delete(), netbuf_alloc()和netbuf_free()等函数来创建、释放和管理netbuf,确保用户数据的正确传输。" 113642144,8014178,Redis 架构演进之路:从单机到分片集群,"['Redis', '后端', '架构']

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

netbuf结构体

LWIP为了更好描述应用线程发送接收的数据,并且为了更好管理这些数据的缓冲区,LWIP定义了一个netbuf结构体,它是基于pbuf上更高一层的封装,记录了主机的ip地址与端口号,端口号对应的就是应用线程,在接收的时候,应用程序肯定需要知道到底是谁发送数据给自己,而在发送的时候,应用程序需要将自己的端口号与IP地址填充到netbuf结构体对应字段中.netbuf结构体

1 struct netbuf
2 {
3 struct pbuf *p, *ptr;                                 (1)
4 ip_addr_t addr;                                       (2)
5 u16_t port;                                           (3)
6 };

(1)netbuf的p字段的指针指向pbuf链表,这是基于pbuf上封装的结构体,因此,ptr字段的指针有一点不一样,因为他可以指向任意的pbuf,由netbuf_next()与netbuf_first()来控制。

(2)addr字段记录了数据发送方的IP地址。

(3)port记录了数据发送方的端口号

LWIP的会定义一些带宏参来快速操作这些结构体的字段。

1 #define netbuf_fromaddr(buf) (&((buf)->addr))
2 #define netbuf_set_fromaddr(buf, fromaddr) \
3 ip_addr_set(&((buf)->addr), fromaddr)
4 #define netbuf_fromport(buf) ((buf)->port)

netbuf结构体指向示意图如下,虚线表示ptr指针的指向位置是不固定的,它是由netbuf_next()函数与netbuf_first()函数来调整

netbuf是LWIP描述用户数据的结构体,因为LWIP是不可能让我们直接操作pbuf的,因为分层的思想,应用数据必然是由用户操作的,因此LWIP会提供很多函数接口让用户对netbuf进行操作,无论是UDP报文还是TCP报文段,要发送出去的数据都会封装在netbuf中,然后通过邮箱发送给内核线程(tcpip_thread)然后经过内核的一系列处理,放入发送队列中,然后调用底层网卡发送函数进行发送,反正,应用线程接收到数据,也是通过netbuf进行管理 。

LWIP提供给我们操作netbuf的相关函数

netbuf_new()

这个函数的功能是申请一个新的netbuf结构体内存空间,通过memp内存池进行申请,大小是MEMP_NETBUF并且将netbuf结构体全部初始化为0,并且返回一个指向netbuf结构体的指针,此时的netbuf结构体的p与ptr字段不指向任何的pbuf.

1 struct
2 netbuf *netbuf_new(void)
3 {
4 struct netbuf *buf;
5
6 buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
7 if (buf != NULL)
8 {
9 memset(buf, 0, sizeof(struct netbuf));
10 }
11 return buf;
12 }

netbuf_delete()

与netbuf_new()函数相反,释放一个netbuf结构体内存空间,如果netbuf结构体的p或者ptr字段字段指向的pbuf是拥有数据的,那么对应的pbuf也会被释放掉,代码如下

1 void
2 netbuf_delete(struct netbuf *buf)
3 {
4 if (buf != NULL)
5 {
6 if (buf->p != NULL)
7 {
8 pbuf_free(buf->p);
9 buf->p = buf->ptr = NULL;
10 }
11 memp_free(MEMP_NETBUF, buf);
12 }
13 }

netbuf_alloc()

这个函数为netbuf结构体中的p字段指向的数据区域分配指定大小的内存空间,简单来说就是申请pbuf内存空间,由于这个函数是应用层调用的,因此这个内存会包含链路层首部,IP层首部大小,当然,这些空间是附加上去的,用户指定的是数据区域会被释放掉,然后重新申请用户指定大小的数据区域,而函数的返回是一个指定数据区域起始地址的指针(即pbuf的payload指针)代码如下

1 void *
2 netbuf_alloc(struct netbuf *buf, u16_t size)
3 {
4 LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;);
5
6 /* Deallocate any previously allocated memory. */
7 if (buf->p != NULL)
8 {
9 pbuf_free(buf->p);
10 }
11 buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
12 if (buf->p == NULL)
13 {
14 return NULL;
15 }
16 LWIP_ASSERT("check that first pbuf can hold size",
17 (buf->p->len >= size));
18 buf->ptr = buf->p;
19 return buf->p->payload;
20 }

netbuf_free()

这个函数的功能是释放netbuf结构体指向的pbuf内存空间,如果结构体中指向pbuf的内容为空,则不做任何释放操作,直接将p与ptr字段的指针设置为NULL代码如下

1 void
2 netbuf_free(struct netbuf *buf)
3 {
4 LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;);
5 if (buf->p != NULL)
6 {
7 pbuf_free(buf->p);
8 }
9 buf->p = buf->ptr = NULL;
10 }

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值