STM32F2xx的tcp_echoserver例程解说

发布者:TechVoyager最新更新时间:2017-09-18 来源: eefocus关键字: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. }  



  
  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
  
  如果网络联通的话,测试成功将如下如下的画面,如图:
  


关键字:STM32F2xx  tcp_echoserver  例程解说 引用地址:STM32F2xx的tcp_echoserver例程解说

上一篇:STM32进入HardFault_Handler处理办法
下一篇:STM32串口如何代码实现更稳定的接收消息

小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved