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;

}

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐