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为广播地址,也就是任意地址的意思。

 

sitemap