lwip的回调函数学习笔记1
ETH_BSP_Config(); //硬件外设初始化
LwIP_Init();//ip地址 网关等初始化
udp_test_init();//使用udp协议时的相关初始化
void udp_test_init(void)
{
struct udp_pcb *pcb;//定义udp协议指针
pcb = udp_new();//新建一个 并开辟空间内存
udp_bind(pcb,IP_ADDR_ANY,2000);//分配IP等
udp_recv(pcb,Udp_Test_Receive,NULL);//将回调函数赋给指针 这个函数中 将回调函数Udp_Test_Receive作为参数传给udp_recv,实际表达的作用就是 这样
// pcb->recv = Udp_Test_Receive
// pcb->recv_arg = 空;
}
Udp_pcb是一个自带链表的的结构体,
struct udp_pcb {
/* Common members of all PCB types */
IP_PCB;
/* Protocol specific PCB members */
struct udp_pcb *next;
u8_t flags;
/** ports are in host byte order */
u16_t local_port, remote_port;
#if LWIP_IGMP
/** outgoing network interface for multicast packets */
ip_addr_t multicast_ip;
#endif /* LWIP_IGMP */
#if LWIP_UDPLITE
/** used for UDP_LITE only */
u16_t chksum_len_rx, chksum_len_tx;
#endif /* LWIP_UDPLITE */
/** receive callback function */
udp_recv_fn recv;
/** user-supplied argument for the recv callback */
void *recv_arg;
};
有*next,是为了可以和多个客户端链接,每个链表都有ip,可以储存不同端口。
仔细分析一下回调函数的作用
void Udp_Test_Receive(void *arg,struct udp_pcb *pcb,struct pbuf *p,struct
ip_addr *addr,u16_t port)
{
//struct ip_addr destAddr = *addr;
//unsigned char g_tData[256];
struct pbuf *p1;
unsigned char *nptr; //指向UDP接收缓存区的指针
short len; //接收到的UDP数据包长度
unsigned short LenUpdata = 0; //升级数据包的有效数据长度
unsigned char ret,saddr;
if(p != NULL)
{
len = p->len;
len = len;
nptr = (unsigned char*)p->payload;
/////////////////////////////////////////////////////////////////
Add your code here
////////////////////////////////////////////////////////////////
pbuf_free(p);//释放
}
使用回调函数实际上就是在调用某个函数(通常是API函数)时,将自己的一个函数(这个函数为回调函数)的地址作为参数传递给那个函数。而那个函数在需要的时候,利用传递的地址调用回调函数,这时你可以利用这个机会在回调函数中处理消息或完成一定的操作。
回调函数只初始化一次就表明以后来数据就只调用该一个回调函数。
其它函数解释
struct tcp_pcb *tcp_new(void)
创建一个新的连接标识符(PCB)。如果没有有效的存储空间创建这个新的pcb,返回NULL。
译注:这个函数创建一个TCP协议控制块,但并不把它放到任何TCP PCB列表,直到使用tcp_bind()函数绑定。Tcp_new()函数会调用tcp_alloc函数来动态申请一块内存并初始化它,之后将这块内存的首地址返回给tcp_new()函数,如果动态内存不成功的话返回NULL。
err_t tcp_bind(struct tcp_pcb *pcb, struct ip_addr
*ipaddr,
u16_t port)
给pcb绑定一个本地IP地址和端口号。如果参数"ipaddr"为IP_ADDR_ANY,则为这个pcb绑定任意本地IP地址。
译注:这个函数的大部分代码用于检验给出的IP地址和端口号是否合适,如果合适则将给出的IP地址和端口号赋给当前PCB,更新已绑定tcp_pcb列表并返回ERR_OK.如果给出的参数不合适,则返回ERR_USE(表示端口已被使用)。
参数ipaddr如果为IP_ADDR_ANY,表示绑定到任意本地地址,那么IP_ADDR_ANY是什么呢?在lwip-1.3.0\src\include\ipv4\lwip\ip_addr.h中定义了:
#define IP_ADDR_ANY
((struct ip_addr *)&ip_addr_any)
ip_addr_any是一个ip_addr型变量,在lwip-1.3.0\src\core\ipv4\ip_addr.c中有如下声明:
#define IP_ADDR_ANY_VALUE 0x00000000UL
const struct ip_addr ip_addr_any = { IP_ADDR_ANY_VALUE };
所以, IP_ADDR_ANY是等于0x00000000UL的. 在IP地址上规定
0.0.0.0为广播地址,也就是任意地址的意思。