接上文:TCP/IP协议栈Lwip的设计与实现:之四_龙赤子的博客-CSDN博客
目录
15.API参考
15.1数据类型
15.2缓冲函数
LWIP使用两种类型的数据,它们是:
1.netbuf网络缓冲抽象
2.Netconn网络连接的抽象
每一个数据类型都作为一个指向C结构的指针来代表。该结构的内部结构信息不应当在应用程序中使用,相反,API提供相关的函数来修改和提取需要的域。
15.1.1 Netbufs
Netbufs是用于发送和接收数据的缓冲。内部,一个netbuf与6.1节出现的一个pbuf关联。Netbufs,就像pbufs,能够适应分配的内存和参考的内存。分配的内存是在RAM中明确分配用来获取网络数据,而参考的内存是有应用管理的RAM或者外部的ROM。参考的内存在发送不被修改的数据,像静态web页面或者图像时是有用的。
Netbuf中的数据可以被分解为不同大小的块,这意味着一个应用必须准备去接收分片的数据。在内部,一个netbuf有一个指向netbuf中一个分片的指针。两个函数netbuf_next()和netbuf_first()被用来管理该指针。
从网络中接收到的netbufs也包含有包原始发送人的IP地址和端口号,同样存在用于提取这些值的函数。
15.2.1 netbuf_new()
函数原型:
struct netbuf * netbuf_new(void)
函数说明:
分配一个netbuf结构体。此时不进行缓冲空间的分配,仅仅是顶层的结构体。使用之后必须调用netbuf_delete()来释放。
15.2.2 netbuf_delete()
函数原型:
void netbuf_delete(struct netbuf *)
函数说明:
释放之前通过调用netbuf_new()分配的netbuf结构体。任何由于调用netbuf_alloc()为netbuf分配的缓冲内存也被释放。
使用举例:
/*****************************************/
int main()
{
struct netbuf * buf;
buf = netbuf_new(); /* create a new netbuf */
netbuf_alloc(buf,100); /* allocate 100 bytes of buffer */
/* do something with the netbuf */
/* […] */
netbuf_delete(buf); /* deallocate netbuf */
}
/******************************************/
15.2.3 netbuf_alloc()
函数原型:
void * netbuf_alloc(struct netbuf *buf, int size)
函数说明:
为netbuf buf分配size数量字节的缓冲内存。该函数返回一个指向已分配内存的指针。任何之前为netbuf buf分配的内存已被释放。分配的内存之后可以被netbuf_free()释放。因为当协议头要发送时,它被期望优先于数据发送,所以,该函数不仅为实际数据分配存储,也为协议头分配内存。
15.2.4 netbuf_free()
函数原型:
int netbuf_free(struct netbuf *buf)
函数说明:
释放与netbuf buf相关联的缓存。如果没有缓存被分配给该netbuf,该函数将不做任何事。
15.2.5 netbuf_ref()
函数原型:
int netbuf_ref(struct netbuf *buf, void *data, int size)
函数说明:
通过data指针使netbuf buf关联于外部内存。外部存储的大小通过size给出。任何之前为netbuf分配的内存被释放。使用netbuf_alloc()为netbuf分配内存与使用malloc()分配内存并使用netbuf_ref()使之参考与该内存的区别就在于在前一中情况下,协议头的空间也被分配,这使得处理和发送缓冲数据更加快速。
使用举例:
/***************************************/
int main()
{
struct netbuf * buf;
char string[] = “A string”;
/* create a new netbuf */
buf = netbuf_new();
/* reference the string */
netbuf_ref(buf, string, sizeof(string));
/* do something with the netbuf */
/* […] */
/* deallocate netbuf */
netbuf_delete(buf);
}
/***************************************/
15.2.6 netbuf_len()
函数原型:
int netbuf_len(struct netbuf *buf)
函数说明:
返回netbuf buf中数据的总长度,即使该netbuf被分解。对于一个分解的netbuf,通过调用该函数获得的值与netbuf中第一个分片的大小不一样。
15.2.7 netbuf_data()
函数原型:
int netbuf_data(struct netbuf *buf, void **data, int *len)
函数说明:
该函数用于获得netbuf buf中一块数据的指针以及该块数据的长度。data和len是可以获得返回结果的参数,data将被指向该数据的指针填充,len将被指向数据长度的指针填充。如果该netbuf被分解,函数将给出netbuf中一个分片的指针。为了得到netbuf中的所有数据,应用程序必须使用分片捕获函数netbuf_frist()和netbuf_next()。
15.2.8 netbuf_next()
函数原型:
int netbuf_next(struct netbuf *buf)
函数说明:
该函数更新netbuf中的内部分片指针,因此它指向netbuf中的下一个分片。如果netbuf中还有更多的分片时返回值为0,如果分片指针当前指向netbuf中的最后一个分片时返回值大于0,如果指针已经指向了最后一个分片,则返回值就小于0。
使用举例:
/************************************/
/* […] */
do{
char *data;
int len;
/* obtain a pointer to the data in fragment */
netbuf_data(buf, &data, &len);
/* do something with the data */
do_something(data, len);
}while(netbuf_next(buf) >= 0)
/* […] */
/************************************/
15.2.9 netbuf_first()
函数原型:
void netbuf_first(struct netbuf *buf)
函数说明:
复位netbuf buf中的分片指针使之指向第一个分片。
15.2.10 netbuf_copy()
函数原型:
void netbuf_copy(struct netbuf *buf, void *data, int len)
函数说明:
拷贝netbuf buf中的所有数据到data指针指向的内存,即使netbuf buf被分解了。len参数是拷贝数据量的上界。
使用举例:
该例子展示了netbuf_copy的简单使用。这里,200字节的数据分配于协议栈上来捕获数据,即使netbuf buf有多于200字节的数据,也仅仅有200字节的数据被拷贝到data指向的内存中。
/**********************************/
void example_function(struct netbuf *buf)
{
char data[200];
netbuf_copy(buf, data, 200);
/* do something with the data */
}
/**********************************/
15.2.11 netbuf_chain()
函数原型:
void netbuf_chain(struct netbuf *head, struct netbuf *tail)
函数说明:
将head和tail两个netbufs连和在一起,这样,tail中的数据将成为head的最后一个分片。tail netbuf被释放,在该函数调用后将不再使用。
15.2.12 netbuf_fromaddr()
函数原型:
struct ip_addr * netbuf_fromaddr(struct netbuf *buf)
函数说明:
返回主机的IP地址,该netbuf buf来自该主机。如果netbuf还没有从网络上接收到,该函数的返回值将是不确定的。函数netbuf_fromport()可以用于获得远程主机的端口号。
15.2.13 netbuf_fromport()
函数原型:
unsigned short netbuf_fromport(struct netbuf *buf)
函数说明:
返回主机的端口号,该主机为发送netbuf的主机。如果该netbuf还没有从网络上接收到,则函数的返回值是不确定的。netbuf_fromaddr()可以用于获得远程主机的IP地址。