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_server_demo.htcp_server_demo.c文件,其内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/\*
\* tcp\_server\_demo.h
\*
\* Created on: 2022年7月15日
\* Author: jenson
\*/

#ifndef TCP\_SERVER\_DEMO\_H\_
#define TCP\_SERVER\_DEMO\_H\_

void handle\_tcp\_server(void);

#endif /\* TCP\_SERVER\_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
/\*
\* tcp\_server\_demo.c
\*
\* Created on: 2022年7月15日
\* Author: jenson
\*/

#include "app\_config.h"

#ifdef TCP\_SERVER\_DEMO
#include <stdio.h>
#include "stm32f1xx\_hal.h"
#include "w5500.h"
#include "tcp\_server\_demo.h"

#define TCP\_DEMO\_BUFFER\_SIZE 2048
uint8\_t __tcp_demo_buffer[TCP_DEMO_BUFFER_SIZE];
#define TCP\_SERVER\_PORT 5000
#define TCP\_SERVER\_SOCK 0

void \_\_handle\_tcp\_server\_data(void) {
// 接收数据长度
uint16\_t len = getSn\_RX\_RSR(TCP_SERVER_SOCK);
if (len > 0) {
// 接收数据
recv(TCP_SERVER_SOCK, __tcp_demo_buffer, TCP_DEMO_BUFFER_SIZE);

printf("recv:%s\r\n", __tcp_demo_buffer);

// 将数据发送回客户端
send(TCP_SERVER_SOCK, __tcp_demo_buffer, len);
}
}

void handle\_tcp\_server(void) {
switch (getSn\_SR(TCP_SERVER_SOCK)) {
case SOCK_INIT: // socket初始化完成
// 监听Socket
listen(TCP_SERVER_SOCK);
break;
case SOCK_ESTABLISHED: // socket连接成功
// 已经建立连接
if (getSn\_IR(TCP_SERVER_SOCK) & Sn_IR_CON) {
setSn\_IR(TCP_SERVER_SOCK, Sn_IR_CON);
}
\_\_handle\_tcp\_server\_data();
break;
case SOCK_CLOSE_WAIT: // socket等待关闭
close(TCP_SERVER_SOCK);
break;
case SOCK_CLOSED: // socket 关闭状态
socket(TCP_SERVER_SOCK, Sn_MR_TCP, TCP_SERVER_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
/\* USER CODE END Includes \*/
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\_SERVER\_DEMO
handle\_tcp\_server();
#endif
}
/\* USER CODE END 3 \*/
}

文章来源: https://iotsmart.blog.csdn.net/article/details/125908640