zoukankan      html  css  js  c++  java
  • stm32+lwip(三):TCP测试

    我是卓波,很高兴你来看我的博客。

    系列文章:

    stm32+lwip(一):使用STM32CubeMX生成项目

    stm32+lwip(二):UDP测试

    stm32+lwip(三):TCP测试

    stm32+lwip(四):网页服务器测试

    stm32+lwip(五):以太网帧发送测试

    ST官方有lwip的例程,下载地址如下:

    https://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-library-expansion/stsw-stm32070.html

    本文例子参考ST官方给出的例程。

    一、准备

    ST例程文档关于lwip的介绍如下:

     

    由此可以看到LWIP有三种API,在本文中,使用Raw API。

    本文用到的TCP Raw API如下:

    二、tcp client

      1 /**
      2   *****************************************************************************
      3   * @file    tcp_client.c
      4   * @author  Zorb
      5   * @version V1.0.0
      6   * @date    2018-09-04
      7   * @brief   tcp客户端的实现
      8   *****************************************************************************
      9   * @history
     10   *
     11   * 1. Date:2018-09-04
     12   *    Author:Zorb
     13   *    Modification:建立文件
     14   *
     15   *****************************************************************************
     16   */
     17 
     18 #include "stm32f4xx_hal.h"
     19 #include "lwip.h"
     20 #include "tcp.h"
     21 #include "string.h"
     22 
     23 /* 定义端口号 */
     24 #define TCP_REMOTE_PORT    8881 /* 远端端口 */
     25 #define TCP_LOCAL_PORT     8880 /* 本地端口 */
     26 
     27 /******************************************************************************
     28  * 描述  : 数据接收回调函数
     29  * 参数  : -
     30  * 返回  : -
     31 ******************************************************************************/
     32 static err_t tcp_client_recv(void *arg, struct tcp_pcb *tpcb,
     33                              struct pbuf *p, err_t err)
     34 {
     35     uint32_t i;
     36     
     37     /* 数据回传 */
     38     //tcp_write(tpcb, p->payload, p->len, 1);
     39     
     40     if (p != NULL)
     41     {
     42         struct pbuf *ptmp = p;
     43         
     44         /* 打印接收到的数据 */
     45         printf("get msg from %d:%d:%d:%d port:%d:
    ",
     46             *((uint8_t *)&tpcb->remote_ip.addr),
     47             *((uint8_t *)&tpcb->remote_ip.addr + 1),
     48             *((uint8_t *)&tpcb->remote_ip.addr + 2),
     49             *((uint8_t *)&tpcb->remote_ip.addr + 3),
     50             tpcb->remote_port);
     51         
     52         while(ptmp != NULL)
     53         {
     54             for (i = 0; i < p->len; i++)
     55             {
     56                 printf("%c", *((char *)p->payload + i));
     57             }
     58             
     59             ptmp = p->next;
     60         }
     61         
     62         printf("
    ");
     63         
     64         tcp_recved(tpcb, p->tot_len);
     65         
     66         /* 释放缓冲区数据 */
     67         pbuf_free(p);
     68     }
     69     else if (err == ERR_OK)
     70     {
     71         printf("tcp client closed
    ");
     72         
     73         tcp_recved(tpcb, p->tot_len);
     74         
     75         return tcp_close(tpcb);
     76     }
     77 
     78     return ERR_OK;
     79 }
     80 
     81 /******************************************************************************
     82  * 描述  : 连接服务器回调函数
     83  * 参数  : -
     84  * 返回  : -
     85 ******************************************************************************/
     86 static err_t tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
     87 {
     88     printf("tcp client connected
    ");
     89     
     90     tcp_write(tpcb, "tcp client connected", strlen("tcp client connected"), 0);
     91 
     92     /* 注册接收回调函数 */
     93     tcp_recv(tpcb, tcp_client_recv);
     94 
     95     return ERR_OK;
     96 }
     97 
     98 /******************************************************************************
     99  * 描述  : 创建tcp客户端
    100  * 参数  : 无
    101  * 返回  : 无
    102 ******************************************************************************/
    103 void tcp_client_init(void)
    104 {
    105     struct tcp_pcb *tpcb;
    106     ip_addr_t serverIp;
    107 
    108     /* 服务器IP */
    109     IP4_ADDR(&serverIp, 192, 168, 2, 194);
    110 
    111     /* 创建tcp控制块 */
    112     tpcb = tcp_new();
    113     
    114     if (tpcb != NULL)
    115     {
    116         err_t err;
    117         
    118         /* 绑定本地端号和IP地址 */
    119         err = tcp_bind(tpcb, IP_ADDR_ANY, TCP_LOCAL_PORT);
    120 
    121         if (err == ERR_OK)
    122         {
    123             /* 连接服务器 */
    124             tcp_connect(tpcb, &serverIp, TCP_REMOTE_PORT, tcp_client_connected);
    125         }
    126         else
    127         {
    128             memp_free(MEMP_TCP_PCB, tpcb);
    129             
    130             printf("can not bind pcb
    ");
    131         }
    132     }
    133 }
    134 
    135 /******************************** END OF FILE ********************************/

    本例用到的上位机IP192.168.2.194,开放端口为8881

    STM32IP192.168.2.8,开放端口为8880

    先将网络调试助手的TCP Server打开,然后给STM32上电。

    网络调试助手将会收到如下信息:

     

    然后点击网络调试助手的发送,STM32调试串口输出以下信息:

    get msg from 192:168:2:194 port:8881:
    hello zorb

    三、tcp server

      1 /**
      2   *****************************************************************************
      3   * @file    tcp_server.c
      4   * @author  Zorb
      5   * @version V1.0.0
      6   * @date    2018-09-04
      7   * @brief   tcp服务端的实现
      8   *****************************************************************************
      9   * @history
     10   *
     11   * 1. Date:2018-09-04
     12   *    Author:Zorb
     13   *    Modification:建立文件
     14   *
     15   *****************************************************************************
     16   */
     17 
     18 #include "stm32f4xx_hal.h"
     19 #include "lwip.h"
     20 #include "tcp.h"
     21 #include "string.h"
     22 
     23 /* 定义端口号 */
     24 #define TCP_REMOTE_PORT    8881 /* 远端端口 */
     25 #define TCP_LOCAL_PORT     8880 /* 本地端口 */
     26 
     27 /******************************************************************************
     28  * 描述  : 接收回调函数
     29  * 参数  : -
     30  * 返回  : -
     31 ******************************************************************************/
     32 static err_t tcp_server_recv(void *arg, struct tcp_pcb *tpcb,
     33                              struct pbuf *p, err_t err)
     34 {
     35     uint32_t i;
     36     
     37     /* 数据回传 */
     38     //tcp_write(tpcb, p->payload, p->len, 1);
     39     
     40     if (p != NULL)
     41     {
     42         struct pbuf *ptmp = p;
     43         
     44         /* 打印接收到的数据 */
     45         printf("get msg from %d:%d:%d:%d port:%d:
    ",
     46             *((uint8_t *)&tpcb->remote_ip.addr),
     47             *((uint8_t *)&tpcb->remote_ip.addr + 1),
     48             *((uint8_t *)&tpcb->remote_ip.addr + 2),
     49             *((uint8_t *)&tpcb->remote_ip.addr + 3),
     50             tpcb->remote_port);
     51         
     52         while(ptmp != NULL)
     53         {
     54             for (i = 0; i < p->len; i++)
     55             {
     56                 printf("%c", *((char *)p->payload + i));
     57             }
     58             
     59             ptmp = p->next;
     60         }
     61         
     62         printf("
    ");
     63         
     64         tcp_recved(tpcb, p->tot_len);
     65         
     66         /* 释放缓冲区数据 */
     67         pbuf_free(p);
     68     }
     69     else if (err == ERR_OK)
     70     {
     71         printf("tcp client closed
    ");
     72         
     73         tcp_recved(tpcb, p->tot_len);
     74         
     75         return tcp_close(tpcb);
     76     }
     77 
     78     return ERR_OK;
     79 }
     80 
     81 /******************************************************************************
     82  * 描述  : 客户端接入回调函数
     83  * 参数  : -
     84  * 返回  : -
     85 ******************************************************************************/
     86 static err_t tcp_server_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
     87 {
     88     printf("tcp client connected
    ");
     89     
     90     printf("ip %d:%d:%d:%d port:%d
    ",
     91         *((uint8_t *)&newpcb->remote_ip.addr),
     92         *((uint8_t *)&newpcb->remote_ip.addr + 1),
     93         *((uint8_t *)&newpcb->remote_ip.addr + 2),
     94         *((uint8_t *)&newpcb->remote_ip.addr + 3),
     95         newpcb->remote_port);
     96     
     97     tcp_write(newpcb, "tcp client connected", strlen("tcp client connected"), 0);
     98     
     99     /* 注册接收回调函数 */
    100     tcp_recv(newpcb, tcp_server_recv);
    101 
    102     return ERR_OK;
    103 }
    104 
    105 /******************************************************************************
    106  * 描述  : 创建tcp服务器
    107  * 参数  : 无
    108  * 返回  : 无
    109 ******************************************************************************/
    110 void tcp_server_init(void)
    111 {
    112     struct tcp_pcb *tpcb;
    113 
    114     /* 创建tcp控制块 */
    115     tpcb = tcp_new();
    116 
    117     if (tpcb != NULL)
    118     {
    119         err_t err;
    120         
    121         /* 绑定端口接收,接收对象为所有ip地址 */
    122         err = tcp_bind(tpcb, IP_ADDR_ANY, TCP_LOCAL_PORT);
    123 
    124         if (err == ERR_OK)
    125         {
    126             /* 监听 */
    127             tpcb = tcp_listen(tpcb);
    128 
    129             /* 注册接入回调函数 */
    130             tcp_accept(tpcb, tcp_server_accept);
    131             
    132             printf("tcp server listening
    ");
    133             printf("tcp server ip:%d:%d:%d:%d prot:%d
    ",
    134                 *((uint8_t *)&ipaddr.addr),
    135                 *((uint8_t *)&ipaddr.addr + 1),
    136                 *((uint8_t *)&ipaddr.addr + 2),
    137                 *((uint8_t *)&ipaddr.addr + 3),
    138                 tpcb->local_port);
    139         }
    140         else
    141         {
    142             memp_free(MEMP_TCP_PCB, tpcb);
    143             
    144             printf("can not bind pcb
    ");
    145         }
    146 
    147     }
    148 }
    149 
    150 /******************************** END OF FILE ********************************/

    本例用到的上位机IP192.168.2.194,开放端口为8881

    STM32IP192.168.2.8,开放端口为8880

    先将STM32上电,STM32调试串口输出以下信息:

    tcp server listening
    tcp server ip:192:168:2:8 prot:8880

    然后通过网络调试助手连接到STM32tcp服务器:

    STM32调试串口输出以下信息:

    tcp client connected
    ip 192:168:2:194 port:53538

    在网络调试助手发送信息”hello zorb”STM32调试串口输出以下信息:

    get msg from 192:168:2:194 port:53538:
    hello zorb

    四、最后

    本文测试了lwiptcp功能,能正常连接并收发数据,撒花。

    github:https://github.com/54zorb/stm32-lwip

    版权所有,转载请打赏哟

    如果你喜欢我的文章,可以通过微信扫一扫给我打赏哟

  • 相关阅读:
    BZOJ_2017_[Usaco2009 Nov]硬币游戏_博弈论+DP
    BZOJ_1916_[Usaco2010 Open]冲浪_分层图+拓扑排序+DP
    BZOJ_1915_[Usaco2010 Open]奶牛的跳格子游戏_DP+单调队列
    读入/输出优化模板
    BZOJ_4327_JSOI2012 玄武密码_AC自动机
    计算机网络学习笔记:第六章.应用层
    计算机网络学习笔记:第五章.传输层
    计算机网络学习笔记:第四章.网络层
    计算机网络学习笔记:第三章.数据链路层
    计算机网络学习笔记:第二章.物理层
  • 原文地址:https://www.cnblogs.com/54zorb/p/9609111.html
Copyright © 2011-2022 走看看