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:\r\n",
 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("\r\n");
 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\r\n");
 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\r\n");
 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\r\n");
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:\r\n",
 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("\r\n");
 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\r\n");
 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\r\n");
 89     
 90     printf("ip %d:%d:%d:%d port:%d\r\n",
 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\r\n");
133             printf("tcp server ip:%d:%d:%d:%d prot:%d\r\n",
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\r\n");
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

版權所有,轉載請打賞喲

 

如果你喜歡我的文章,可以通過微信掃一掃給我打賞喲


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM