STM32F1网络编程-TCP客户端(基于W5500网卡) TCP客户端(基于W5500网卡) 在前面的文章中,我们实现了W5500的驱动移植并实现了W5500的静态IP设置和动态IP获取。本次实例将简单实现一个简单的TCP客户端,实现与TCP服务器通信。对于TCP协议在这里不做介绍,请参考相关专业资料。
W5500客户端实现的主要步骤如下:
1)查询socket状态。通过调用W5500驱动API的getSn_SR查询socket状态。(注意:W5500支持的socket编号为0~7)
2)当socket状态为SOCK_INIT时,连接服务器
3)当socket状态为SOCK_ESTABLISHED时,可以向服务器接收或发送数据。
4)当socket状态为SOCK_CLOSE_WAIT时,关闭socket
在STM32CubeIDE工程的Application目录下分别创建tcp_client_demo.h和tcp_client_demo.c文件,其内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 /\* \* tcp\_client\_demo.h \* \* Created on: 2022年7月15日 \* Author: jenson \*/ #ifndef TCP\_CLIENT\_DEMO\_H\_ #define TCP\_CLIENT\_DEMO\_H\_ void handle\_tcp\_client(void); #endif /\* TCP\_CLIENT\_DEMO\_H\_ \*/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 /\* \* tcp\_demo.c \* \* Created on: 2022年7月15日 \* Author: jenson \*/ #include "app\_config.h" #ifdef TCP\_CLIENT\_DEMO #include "stm32f1xx\_hal.h" #include "w5500.h" #include "tcp\_client\_demo.h" #define TCP\_CLIENT\_SOCK 0 #define TCP\_DEMO\_BUFFER\_SIZE 2048 uint8\_t __tcp_demo_buffer[TCP_DEMO_BUFFER_SIZE]; const uint8\_t TCP_SERVER_IP[] = { 192, 168, 2, 78 }; #define TCP\_SERVER\_PORT 5000 #define TCP\_LOCAL\_PORT 6000 void \_\_handle\_tcp\_client\_data(void) { uint16\_t len = 0; // 接收数据长度 len = getSn\_RX\_RSR(TCP_CLIENT_SOCK); if (len > 0) { // 接收数据 recv(TCP_CLIENT_SOCK, __tcp_demo_buffer, TCP_DEMO_BUFFER_SIZE); printf("recv:%s\r\n",__tcp_demo_buffer); // 将数据发送回服务器 send(TCP_CLIENT_SOCK,__tcp_demo_buffer,len); } } void handle\_tcp\_client(void) { switch (getSn\_SR(TCP_CLIENT_SOCK)) { case SOCK_INIT: // socket初始化完成 // 连接Socket connect(TCP_CLIENT_SOCK, TCP_SERVER_IP, TCP_SERVER_PORT); break; case SOCK_ESTABLISHED: // socket连接成功 // 已经建立连接 if (getSn\_IR(TCP_CLIENT_SOCK) & Sn_IR_CON) { setSn\_IR(TCP_CLIENT_SOCK, Sn_IR_CON); } \_\_handle\_tcp\_client\_data(); break; case SOCK_CLOSE_WAIT: // socket等待关闭 close(TCP_CLIENT_SOCK); break; case SOCK_CLOSED: // socket 关闭状态 socket(TCP_CLIENT_SOCK, Sn_MR_TCP, TCP_LOCAL_PORT, Sn_MR_ND); break; } } #endif
最后,在main.c文件中,实现调用测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 /\* Private includes ----------------------------------------------------------\*/ /\* USER CODE BEGIN Includes \*/ #include <stdio.h> #include "w5500\_port.h" #include <string.h> // memcmp #include "app\_config.h" #ifdef TCP\_CLIENT\_DEMO #include "tcp\_client\_demo.h" #endif int main(void) { /\* USER CODE BEGIN 1 \*/ /\* USER CODE END 1 \*/ /\* MCU Configuration--------------------------------------------------------\*/ /\* Reset of all peripherals, Initializes the Flash interface and the Systick. \*/ HAL\_Init(); /\* USER CODE BEGIN Init \*/ /\* USER CODE END Init \*/ /\* Configure the system clock \*/ SystemClock\_Config(); /\* USER CODE BEGIN SysInit \*/ /\* USER CODE END SysInit \*/ /\* Initialize all configured peripherals \*/ MX\_GPIO\_Init(); MX\_USART1\_UART\_Init(); MX\_SPI1\_Init(); /\* USER CODE BEGIN 2 \*/ printf("-----STM32 W5500 Ethernet Demo-----\r\n"); w5500\_restart(); // hardware restart through RESET pin wiznet\_register(); w5500\_network\_init\_static(); wiznet\_chip\_config(); /\* USER CODE END 2 \*/ /\* Infinite loop \*/ /\* USER CODE BEGIN WHILE \*/ while (1) { /\* USER CODE END WHILE \*/ //loopback\_tcpc(0, (uint8\_t\*) recv\_buff, destip, destport); /\* USER CODE BEGIN 3 \*/ #ifdef TCP\_CLIENT\_DEMO handle\_tcp\_client(); #endif } /\* USER CODE END 3 \*/ }
文章来源: https://iotsmart.blog.csdn.net/article/details/125908584
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!