项目中遇到需要在STM32F767上创建一个TCP Server,并且允许偶尔有多个客户端同时连接。之前一直使用STM32CubeMX自动创建freeRTOS线程,也只使用过TCP Client模式,这次开发就遇到了问题,归根结底是自己对freeRTOS和LWIP不是太了解,为此利用周末时间专门研究了一下。
这次问题参考了《野火LwIP 应用开发实战指南:基于STM32》以及《嵌入式网络那些事LwIP协议深度剖析与实战演练》
一、实现TCP Server的并发处理的总体思想:
1、利用一个TCPServer主线程监控客户端接入,如果有客户端接入到服务器,那么分配连接句柄给第二个子任务处理数据接收,同时启动子任务线程。
2、子任务读取数据,如果出错或者需要关闭连接的时候,关闭连接,并osThreadExit()退出线程。
3、事先准备好允许的最大数量的存储空间,用来存储连接句柄和读数据的buffer等。
二、代码实现
本次demo允许最大三个线程。
1、准备好1各主线程和三个子线程的句柄和参数,这一部分还是参照STM32CubeMX自动创建的代码复制然后修改后来的,没办法,还是太懒。。。
// 定义对多连接的个数
#define DEF_TCP_SERVER_LISTEN_MAX 3
// TCP Server主任务句柄及参数
osThreadId_t TCPServerTaskHandle;
const osThreadAttr_t TCPServerTask_attributes = {
.name = "TCPServerTask",
.stack_size = 256 * 4,
.priority = (osPriority_t) osPriorityBelowNormal,
};
// 子任务1句柄及参数
osThreadId_t TCPClient1TaskHandle;
osThreadAttr_t TCPClient1Task_attributes = {
.name = "TCPClient1Task",
.stack_size = 256 * 4,
.priority = (osPriority_t) osPriorityLow,
};
// 子任务2句柄及参数
osThreadId_t TCPClient2TaskHandle;
osThreadAttr_t TCPClient2Task_attributes = {
.name = "TCPClient2Task",
.stack_size = 256 * 4,
.priority = (osPriority_t) osPriorityLow,
};
// 子任务3句柄及参数
osThreadId_t TCPClient3TaskHandle;
osThreadAttr_t TCPClient3Task_attributes = {
.name = "TCPClient3Task",
.stack_size = 256 * 4,
.priority = (osPriority_t) osPriorityLow,
};