uip协议栈分析(1)
Uip源代码可以从http://www.sics.se/~adam/uip/index.php/Main_Page上下载得到。 Uip的源码目录结构: D:.├─apps│ ├─dhcpc│ ├─hello-world│ ├─resolv│ ├─smtp│ ├─telnetd│ ├─webclient│ └─webserver│
Uip源代码可以从http://www.sics.se/~adam/uip/index.php/Main_Page上下载得到。
Uip的源码目录结构:
D:.
├─apps
│ ├─dhcpc
│ ├─hello-world
│ ├─resolv
│ ├─smtp
│ ├─telnetd
│ ├─webclient
│ └─webserver
│ └─httpd-fs
├─doc
│ └─html
├─lib
├─sourceinsight
├─uip
└─unix
App目录是一些应用层的协议和实例,Doc目录是文档,lib目录下有内存块管理函数,uip下uip协议栈的源代码,unix下是unix环境里的uip应用例子。
研究unix下的代码可以知道uip是如何使用的,关键是理解uip协议栈的主控制循环。
int main(void)
{
int i;
uip_ipaddr_t ipaddr;
struct timer periodic_timer, arp_timer;
//设置TCP超时处理时间和ARP老化时间
timer_set(&periodic_timer, CLOCK_SECOND / 2);
timer_set(&arp_timer, CLOCK_SECOND * 10);
//驱动初始化
tapdev_init();
//协议栈初始化
uip_init();
//设置IP地址、网关等参数
uip_ipaddr(ipaddr, 192,168,0,2);
uip_sethostaddr(ipaddr);
uip_ipaddr(ipaddr, 192,168,0,1);
uip_setdraddr(ipaddr);
uip_ipaddr(ipaddr, 255,255,255,0);
uip_setnetmask(ipaddr);
//应用层初始化
httpd_init();
//主循环
while(1)
{
//从网卡读取数据
uip_len = tapdev_read();
//如果数据存在则按协议处理
if(uip_len > 0)
{
//如果收到的是IP数据,调用uip_input()处理
if(BUF->type == htons(UIP_ETHTYPE_IP))
{
uip_arp_ipin();
uip_input();
/* 处理完成后如果UIP_BUF里有数据,即
uip_len>0,则调用tapdev_send发送出去*/
if(uip_len > 0) {
uip_arp_out();
tapdev_send();
}
}
//如果收到的是ARP数据,调用uip_arp_arpin处理
else if(BUF->type == htons(UIP_ETHTYPE_ARP))
{
uip_arp_arpin();
/* 查看是否有要发送的数据并发送*/
if(uip_len > 0)
{
tapdev_send();
}
}
}
//查看0.5s是否到了,调用uip_periodic处理TCP超时程序
else if(timer_expired(&periodic_timer))
{
timer_reset(&periodic_timer);
for(i = 0; i < UIP_CONNS; i++)
{
uip_periodic(i);
if(uip_len > 0)
{
uip_arp_out();
tapdev_send();
}
}
#if UIP_UDP
//处理udp超时程序
for(i = 0; i < UIP_UDP_CONNS; i++)
{
uip_udp_periodic(i);
if(uip_len > 0)
{
uip_arp_out();
tapdev_send();
}
}
#endif /* UIP_UDP */
/* 10s到了就处理ARP*/
if(timer_expired(&arp_timer))
{
timer_reset(&arp_timer);
uip_arp_timer();
}
}
}
return 0;
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)