contiki学习笔记-UDP-Client原厂代码分析
来源:互联网 发布:mac 图形驱动 编辑:程序博客网 时间:2024/04/28 17:02
接触contiki一段时间了,但是苦于资料比较少,而且基本上都是入门级别的资料,所以学习起来非常的吃力。于是只能拿官方的实例代码进行剖析。对于udp-client.c这个文件先进行分析。
首先看一下整个的流程。
PROCESS_THREAD(udp_client_process, ev, data){ static struct etimer et;//定时器 uip_ipaddr_t ipaddr;//地址 PROCESS_BEGIN(); PRINTF("UDP client process started\n");#if UIP_CONF_ROUTER set_global_address();#endif print_local_addresses();//打印所有本地可用的地址 static resolv_status_t status = RESOLV_STATUS_UNCACHED; while(status != RESOLV_STATUS_CACHED) { status = set_connection_address(&ipaddr);//设定连接的远端IP地址/* 处理一些异常情况*/ if(status == RESOLV_STATUS_RESOLVING) { PROCESS_WAIT_EVENT_UNTIL(ev == resolv_event_found); } else if(status != RESOLV_STATUS_CACHED) { PRINTF("Can't get connection address.\n"); PROCESS_YIELD(); } } /* new connection with remote host 这里和普通的socket编程一样,先申请一个conn,再进行绑定,其中conn中包括远端的IP地址 */ client_conn = udp_new(&ipaddr, UIP_HTONS(3000), NULL); udp_bind(client_conn, UIP_HTONS(3001)); PRINTF("Created a connection with the server "); PRINT6ADDR(&client_conn->ripaddr);//将一个IPV6地址打印出来 PRINTF(" local/remote port %u/%u\n",UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport)); etimer_set(&et, SEND_INTERVAL);//设定定时器 while(1) { PROCESS_YIELD(); if(etimer_expired(&et)) {//定时器到时间 timeout_handler(); etimer_restart(&et); } else if(ev == tcpip_event) {//收到响应信息 tcpip_handler(); } } PROCESS_END();}我们再对其中的几个函数进行分析。
static voidprint_local_addresses(void){ int i; uint8_t state; PRINTF("Client IPv6 addresses: "); for(i = 0; i < UIP_DS6_ADDR_NB; i++) { state = uip_ds6_if.addr_list[i].state; if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); PRINTF("\n"); } }}
这个函数的主要作用就是打印一下可用的IP地址。UIP_DS6_ADDR_NB这个应该是IPV6的地址的数量,在原厂代码中为3.uip_ds6_if是uip-ds6中定义的一个数据结构,包含了所有的接口变量。它的格式为
typedef struct uip_ds6_netif { uint32_t link_mtu; uint8_t cur_hop_limit; uint32_t base_reachable_time; /* in msec */ uint32_t reachable_time; /* in msec */ uint32_t retrans_timer; /* in msec */ uint8_t maxdadns; uip_ds6_addr_t addr_list[UIP_DS6_ADDR_NB]; uip_ds6_aaddr_t aaddr_list[UIP_DS6_AADDR_NB]; uip_ds6_maddr_t maddr_list[UIP_DS6_MADDR_NB];} uip_ds6_netif_t;
addr_list中就是所有的IPV6地址。for循环就是将其中的IPV6地址都查找一遍,看它的状态。IPV6的地址有三种状态,一种是PREFERRED,代表IPV6地址可用。第二种是TENTATIVE,代表未知。最后一种代表其他主机正在使用,DEPRECATED。
static resolv_status_tset_connection_address(uip_ipaddr_t *ipaddr){#ifndef UDP_CONNECTION_ADDR#if RESOLV_CONF_SUPPORTS_MDNS#define UDP_CONNECTION_ADDR contiki-udp-server.local#elif UIP_CONF_ROUTER#define UDP_CONNECTION_ADDR aaaa:0:0:0:0212:7404:0004:0404#elseRESOLV_CONF_SUPPORTS_MDNS#define UDP_CONNECTION_ADDR contiki-udp-server.local#elif#define UDP_CONNECTION_ADDR fe80:0:0:0:6466:6666:6666:6666#endif#endif /* !UDP_CONNECTION_ADDR */#define _QUOTEME(x) #x#define QUOTEME(x) _QUOTEME(x) resolv_status_t status = RESOLV_STATUS_ERROR; if(uiplib_ipaddrconv(QUOTEME(UDP_CONNECTION_ADDR), ipaddr) == 0) {//如果不能转换成Ipv6地址成功 uip_ipaddr_t *resolved_addr = NULL; status = resolv_lookup(QUOTEME(UDP_CONNECTION_ADDR),&resolved_addr); if(status == RESOLV_STATUS_UNCACHED || status == RESOLV_STATUS_EXPIRED) { PRINTF("Attempting to look up %s\n",QUOTEME(UDP_CONNECTION_ADDR)); resolv_query(QUOTEME(UDP_CONNECTION_ADDR)); status = RESOLV_STATUS_RESOLVING; } else if(status == RESOLV_STATUS_CACHED && resolved_addr != NULL) { PRINTF("Lookup of \"%s\" succeded!\n",QUOTEME(UDP_CONNECTION_ADDR));这段代码看似复杂,实现的功能相当的简单,就是将IPV6地址赋值到ipaddr当中。首先定义UDP_CONNECTION_ADDR变量,这个变量的作用就是放置文本型的IPV6地址。为了方便,需要将文本型的(也就是直接给的那种128位地址)转换成通用的格式。这一大段定义不好阅读,就是根据各自的情况来进行赋值。QUOTEME(x)的作用是将一个地址转换成字符串。在这里,转换的过程相当的复杂,有各自状态,这里就不详细说了。if内是转换不成功的情况,会针对不成功的情况进行处理。
0 0
- contiki学习笔记-UDP-Client原厂代码分析
- contiki学习笔记-udp-server.c文件详细的解析
- contiki SLIP代码分析
- Contiki学习笔记
- Contiki学习笔记:目录
- Contiki学习笔记:目录
- Contiki学习笔记
- contiki学习笔记1:helloworld+process结构分析
- UDP server,client 代码
- 【代码积累】UDP client
- contiki学习笔记——cc2530dk例程实践和UDP重启问题解决
- contiki学习笔记之hello_world
- contiki学习笔记 clock部分
- contiki学习笔记 etimer部分
- contiki学习笔记之leds
- Contiki学习笔记3:定时器
- redis 学习笔记-client端示例代码
- contiki学习笔记 spi部分解析
- Android FileObserver
- memcache过期时间的一点小小的分析
- Adaptor
- C++ 容器vector 理解
- oracle 字符集扫描工具Character Set Scanner
- contiki学习笔记-UDP-Client原厂代码分析
- Android应用自动更新功能的实现!!!
- C++
- 隋炀帝杨广
- [ASP.net教程][译]《学习HTML5游戏编程》第一章
- 用程序员思维、程序设计师思维两种方式写求斐波那契数列的方法。
- php连接mysql数据库
- 浏览器应用开发常用知识
- PHP魔术方法总结