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

版权所有,转载请打赏哟

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

原文地址:https://www.cnblogs.com/54zorb/p/9609111.html