simple_udp_register中回掉函数解析

simple-udp.c中的simple_udp_register()函数的解析,重点为回掉函数,结合broadcast-udp.c这个例子对其进行分析。

broadcast-udp.c是基于simple-udp的一个广播数据报的例子。


int simple_udp_register(structsimple_udp_connection *c,

                    uint16_t local_port,

                    uip_ipaddr_t *remote_addr,

                   uint16_t remote_port,

                    simple_udp_callback receive_callback)

该函数的声明在simple-udp.h头文件进行声明,注册一个UDP连接

receive_callback 一个指针,指向一个函数,该函数在接收到数据包时将被调用

返回值:0,无法分配UDP连接;1,连接成功分配

该函数注册一个UDP连接,同时附加一个回调函数给它。该毁掉函数在有数据包到来时将被调用。本地UDP端口可以设置为0来表示一个临时的UDP端口应当被分配。远程IP地址可以为空,表示来自任何IP地址的数据包应当被接受。


同时,在该头文件中,也声明了simple_udp_callback回掉函数,需要注意的是,这里只是声明,真正的实现是在调用方broadcast-udp.c这个例子程序中。

回调函数:typedef void (*simple_udp_callback)(struct simple_udp_connection *c,

                                     constuip_ipaddr_t *source_addr,

                                     uint16_tsource_port,

                                     constuip_ipaddr_t *dest_addr,

                                     uint16_tdest_port,

                                     constuint8_t *data, uint16_t datalen);

声明一个回调函数指针,并将其转换成simple_udp_callback类型。(声明在simple-udp.h中

但该回调函数的实现是在例子程序broadcast-udp.c中通过名为recerver的函数实现的。

这是回调函数的典型应用实例。


simple_udp_register函数中对回掉函数进行了赋值,通过下面这行代码:

c->receive_callback = receive_callback

这句话看起来像是赋值,其实receive_callback都是指针,这样,两个指针是指向了同一个内存空间,即回调函数,在本例中,也就是broadcast-udp.c中的receiver函数,这样对c->receive_callback的操作就等同于receiver的操作,这样就明白了receiver其实是通过c->receive_callback进行赋值的(这种用法在contiki中很常见),赋值过程发生在simple-udp.c的进程处理函数中,如下:

 if(c->receive_callback != NULL) {

           PROCESS_CONTEXT_BEGIN(c->client_process);

           c->receive_callback(c,

                                &(UIP_IP_BUF->srcipaddr),

                               UIP_HTONS(UIP_IP_BUF->srcport),

                                &(UIP_IP_BUF->destipaddr),

                               UIP_HTONS(UIP_IP_BUF->destport),

                                databuffer,uip_datalen());

           PROCESS_CONTEXT_END();

 其中,

#define UIP_IP_BUF   ((struct uip_udpip_hdr*)&uip_buf[UIP_LLH_LEN])

而,

/* The UDP and IP headers. */
struct uip_udpip_hdr {
#if UIP_CONF_IPV6
  /* IPv6 header. */
  uint8_t vtc,
    tcf;
  uint16_t flow;
  uint8_t len[2];
  uint8_t proto, ttl;
  uip_ip6addr_t srcipaddr, destipaddr;
#else /* UIP_CONF_IPV6 */
  /* IP header. */
  uint8_t vhl,
    tos,
    len[2],
    ipid[2],
    ipoffset[2],
    ttl,
    proto;
  uint16_t ipchksum;
  uip_ipaddr_t srcipaddr, destipaddr;
#endif /* UIP_CONF_IPV6 */
  
  /* UDP header. */
  uint16_t srcport,
    destport;
  uint16_t udplen;
  uint16_t udpchksum;
};

这样就明白&(UIP_IP_BUF->srcipaddr)的含义就是指向源地址;UIP_IP_BUF->srcport指向端口号。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值