我是卓波,很高兴你来看我的博客。
系列文章:
stm32+lwip(一):使用STM32CubeMX生成项目
ST官方有lwip的例程,下载地址如下:
本文例子参考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 ********************************/
本例用到的上位机IP为192.168.2.194,开放端口为8881
STM32的IP为192.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 ********************************/
本例用到的上位机IP为192.168.2.194,开放端口为8881
STM32的IP为192.168.2.8,开放端口为8880
先将STM32上电,STM32调试串口输出以下信息:
tcp server listening
tcp server ip:192:168:2:8 prot:8880
然后通过网络调试助手连接到STM32的tcp服务器:
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
四、最后
本文测试了lwip的tcp功能,能正常连接并收发数据,撒花。
github:https://github.com/54zorb/stm32-lwip
版权所有,转载请打赏哟
如果你喜欢我的文章,可以通过微信扫一扫给我打赏哟
来源:oschina
链接:https://my.oschina.net/u/4269305/blog/3834283