STM32F2xx的tcp_echoserver例程解說

/=====================================================================
//TITLE:
//    STM32F2xx的tcp_echoserver例程解說
//AUTHOR:
//    norains
//DATE:
//    Monday  04-July-2011
//Environment:
//    Keil MDK 4.2
//    STM32F207 核心版
//=====================================================================

     最近拿到STM32F207的核心版,板載有網卡芯片,自然要拿過來搗鼓一番。而對於一個從未接觸過網絡的菜鳥來說,最好的入門方式就是揣測ST公司的例程,所以今天norains也不例外。那麼我們就一起來看看這個官方的例程吧!

    首先我們來了解C/S網絡程序的工作流程,如圖:

 


    這個圖並不是norains所繪製的,而是網上流傳的一個名爲《TCP/IP Socket網絡編程》的PPT所截取的。這個流程各位一定要熟悉,因爲接下來所描述的例子流程,和該圖例非常吻合。

    ST關於TCP的例程分爲client和server,根據字面意思,可以知道tcp_echoserver例程是將STM32F2xx作爲server來用。而例程的第一步呢,便是初始化,調用的是tcp_echoserver_init()函數。

    在tcp_echoserver_init()函數裏,主要做了這麼幾件事情:
     1. 創建一個新的TCP協議控制塊
     2. 綁定地址和端口號(port)
     3. 開始監聽(listen)
     4. 設置accept的回調函數

    其完整代碼如下:

  1. void tcp_echoserver_init(void)  
  2. {  
  3.   //創建一個新的TCP控制塊  
  4.   tcp_echoserver_pcb = tcp_new();  
  5.   
  6.   if (tcp_echoserver_pcb != NULL)  
  7.   {  
  8.     err_t err;  
  9.       
  10.     //綁定到端口7  
  11.     err = tcp_bind(tcp_echoserver_pcb, IP_ADDR_ANY, 7);  
  12.       
  13.     if (err == ERR_OK)  
  14.     {  
  15.       //開始監聽  
  16.       tcp_echoserver_pcb = tcp_listen(tcp_echoserver_pcb);  
  17.         
  18.       //設置tcp_echoserver_accept爲accept的回調函數  
  19.       tcp_accept(tcp_echoserver_pcb, tcp_echoserver_accept);  
  20.     }  
  21.     else   
  22.     {  
  23.       printf("Can not bind pcb\n");  //norains 2011-7-4 comment  
  24.     }  
  25.   }  
  26.   else  
  27.   {  
  28.     printf("Can not create new pcb\n");   //norains 2011-7-4 comment  
  29.   }  
  30. }  

 

    當客戶端開始連接之後,那麼被設置的tcp_echoserver_accept()回調函數就會被調用。該函數主要是創建一個新的數據結構,並且將該數據結構傳遞給底層的TCP,最後分別是設置receive,error和poll這三個回調函數。
  
  tcp_echoserver_accept()代碼如下所示:

  1. static err_t tcp_echoserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err)  
  2. {  
  3.   err_t ret_err;  
  4.   struct tcp_echoserver_struct *es;  
  5.   
  6.   LWIP_UNUSED_ARG(arg);  
  7.   LWIP_UNUSED_ARG(err);  
  8.   
  9.   ///給新的連接設置優先級  
  10.   tcp_setprio(newpcb, TCP_PRIO_MIN);  
  11.   
  12.   //分配一個結構體空間以保持TCP的連接  
  13.   es = (struct tcp_echoserver_struct *)mem_malloc(sizeof(struct tcp_echoserver_struct));  
  14.   if (es != NULL)  
  15.   {  
  16.     es->state = ES_ACCEPTED;  
  17.     es->pcb = newpcb;  
  18.     es->p = NULL;  
  19.       
  20.     //傳遞新分配的結構體數據給新的pcb  
  21.     tcp_arg(newpcb, es);  
  22.       
  23.     //爲新的連接設置receive回調函數   
  24.     tcp_recv(newpcb, tcp_echoserver_recv);  
  25.       
  26.     //爲新的連接設置error回調函數  
  27.     tcp_err(newpcb, tcp_echoserver_error);  
  28.       
  29.     //爲新的連接設置poll回調函數  
  30.     tcp_poll(newpcb, tcp_echoserver_poll, 1);  
  31.       
  32.     ret_err = ERR_OK;  
  33.   }  
  34.   else  
  35.   {  
  36.     /* return memory error */  
  37.     ret_err = ERR_MEM;  
  38.   }  
  39.   return ret_err;    
  40. }  



  
  接下來便是tcp_echoserver_recv()這個回調函數,因爲該函數比較大,這裏就不再全部羅列代碼了。對於使用者來說,只需要知道相應的判定條件來代表什麼意思就足夠了,如:

  1. static err_t tcp_echoserver_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)  
  2. {  
  3.   struct tcp_echoserver_struct *es;  
  4.   err_t ret_err;  
  5.   
  6.   LWIP_ASSERT("arg != NULL",arg != NULL);  
  7.     
  8.   es = (struct tcp_echoserver_struct *)arg;  
  9.   
  10.   if (p == NULL)  
  11.   {  
  12.    //如果接收到空的幀,則釋放連接  
  13.    ...  
  14.   }     
  15.   else if(err != ERR_OK)  
  16.   {  
  17.    //接收到一個非空的幀,但可能某些原因出錯,導致返回值不爲ERR_OK,故在此釋放緩存  
  18.    ...  
  19.   }  
  20.   else if(es->state == ES_ACCEPTED)  
  21.   {  
  22.    //連接成功,在這裏需要設置sent回調函數  
  23.    ...  
  24.   }  
  25.   else if (es->state == ES_RECEIVED)  
  26.   {  
  27.    //從客戶端收到數據  
  28.    ...  
  29.   }  
  30.   else  
  31.   {  
  32.    //當連接關閉時,還收到了數據  
  33.    ...  
  34.   
  35.   }  
  36.     
  37.   return ret_err;  
  38. }  
  39.  STM32F207的代碼部分就暫時說到這裏,現在的問題是,如何測試這代碼的正確性呢?這就必須用到ST提供的echotool.exe程序了。該程序位於stm32f2x7_eth_lwip的PC_Software文件夾中。該程序必須在命令行打開,其大致參數如下所示:
      
      
      如果我們的serverip地址爲192.168.0.8,那麼可以輸入如下命令進行測試:
      echotool.exe 192.168.0.8 /p tcp /r 7 /n 15 /t 2 /d Testing LwIP TCP echo server
      
      如果網絡聯通的話,測試成功將如下如下的畫面,如圖:
      
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章