2009-05-16 00:46:28
标签: 职场  休闲
原创作品,允许转载,转载时请务必以超链接形式标明文章  原始出处 、作者信息和本声明。否则将追究法律责任。 http://bluefish.blog.51cto.com/214870/158419
2009-05-15 LWIP之 SOCKET编程
 
前几天看了关于 LWIP协议栈的实现和FREERTOS的基本原理。今天开始调试LWIP的socket通信,是基于freertos系统的ARM9_STR91X_IAR开发板。
这是个现成的实例,由于 lwip已经由freertos移植好了,而调试的目的就是实现在lwip上的socket通信。本来以为很容易的问题,结果还是搞了一天,当然和EWARM工具的难用也还是有很大关系的。
 
首先要注意的一点是 sys_thread_new和xTaskCreate的区别。我们知道xTaskCreate是用来创建一个task任务的。类似于windows下的process。
/*
  Starts a new thread with priority "prio" that will begin its execution in the
  function "thread()". The "arg" argument will be passed as an argument to the
  thread() function. The id of the new thread is returned. Both the id and
  the priority are system dependent.
*/
sys_thread_t sys_thread_new(void (* thread)(void *arg), void *arg, int prio)
{
xTaskHandle CreatedTask;
int result;
 
    result = xTaskCreate(thread, ( signed portCHAR * ) s_sys_arch_state.cTaskName, s_sys_arch_state.nStackDepth, arg, prio, &CreatedTask );
 
    // For each task created, store the task handle (pid) in the timers array.
    // This scheme doesn't allow for threads to be deleted
    timeoutlist[nextthread++].pid = CreatedTask;
 
    if(result == pdPASS)
    {
        ++s_sys_arch_state.nTaskCount;
       
        return CreatedTask;
    }
    else
    {
        return NULL;
    }
}
很显然, sys_thread_new最终对task的创建也是通过xTaskCreate来实现的。但是请注意不同点,前者会把新创建的task的pid放入到一个timeoutlist的链表中。
起初我也没有主要这个小问题,直到用 socket系列函数的select的时候,一直过不去,而是abort中断了,具体原因请看select函数实现,其中sys_arch_timeouts的调用就是获取当前task的timeout,如果没有用sys_thread_new创建的话,这里就没有我用来调用select的当前task,所以就有了以后的abort中断了。
 
下面给一个 socket编程的实现
static void vLWIPSendTask( void *pvParameters )
{
    int listenfd;
    int remotefd;
    int len;
    struct sockaddr_in local_addr,remote_addr; 
        fd_set readset;
        fd_set writeset;
        struct timeval timeout;
        timeout.tv_sec = 1;
        timeout.tv_usec = 0;
 
 
    //struct lwip_socket* sock;
 
    listenfd = socket(AF_INET,SOCK_STREAM,0);
 
    local_addr.sin_family = AF_INET;
    local_addr.sin_port = htons(80);
    local_addr.sin_len = sizeof(local_addr);
    local_addr.sin_addr.s_addr = INADDR_ANY;
   
    if (bind(listenfd, (struct sockaddr *) &local_addr, sizeof(local_addr)) < 0)
    {
        return ;
    }
 
    if (listen(listenfd, 1) == -1)
    {
        return;
    }
 
    len = sizeof(remote_addr);
        while(1)
        {
      //这里注意一下, lwip的阻塞不是在listen函数,而是accept
      remotefd = accept(listenfd, (struct sockaddr *)&remote_addr, &len);
          //close(listenfd);
          //listenfd = -1;
      //getpeername(remotefd, (struct sockaddr *)&remote_addr, &len);
          if(remotefd != -1)
          {
            int ret;
            send(remotefd,"start to work!\r\n",16,0);
            for(;;)
            {
              FD_ZERO(&readset);
              FD_ZERO(&writeset);
              FD_SET(remotefd, &readset);
              FD_SET(remotefd, &writeset);
 
              ret = lwip_select(remotefd+1, &readset, &writeset, 0, &timeout);
                    
              if(ret > 0)
              {
                if (FD_ISSET(remotefd, &readset))
                {
                  memset(buf,0,50);
                  if(recv(remotefd,buf,50,0) <= 0)
                  {
                    close(remotefd);
                    remotefd = -1;
                    break;
                  }
                  else
                  {
                    int i = strlen(buf);
                    send(remotefd,buf,i ,0);
                  }
                }
                /*
                else if(FD_ISSET(remotefd, &writeset))
                {
                   send(remotefd,"this is time to send!\r\n",25,0);
                }
                */
              }
              else if(ret < 0)
              {
                close(remotefd);
                remotefd = -1;
                break;
              } 
             
            }
          }
        }
       
        vTaskDelete( NULL );
}
对的,这是作为 server端实现的,可以和通用的socket客户端配。经过测试至少可以与windows上的socket程序匹配(接收,发送数据)。
本文出自 “ bluefish” 博客,请务必保留此出处 http://bluefish.blog.51cto.com/214870/158419