当前位置: 首页 > news >正文

FreeRTOS Lwip Socket APi TCP Server 1对多

源文件

/********************************************************************************* @file         lwip_tcp_driver.cpp* @brief        TCP Server implementation using LwIP******************************************************************************* @attention* @author       by syf*******************************************************************************/#include "lwip_tcp_driver.h"
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include <cstring> // For memsetstatic const char send_data[8] = {0xff,0x44,0x55,0x66,0xdd};namespace lwip_tcp {struct client_info *client_fo;
struct client_task_info *client_task_fo;
struct link_socket_info *socket_link_info;// 发送数据的任务
void send_task(void *param) {struct client_info* client = (struct client_info *)param;const char *data_to_send = "Hello, Client!";int data_length = strlen(data_to_send);while (1) {// 发送数据到客户端int sent_bytes = send(client->socket_num, data_to_send, data_length, 0);if (sent_bytes < 0) {debug_print("Failed to send data to client[%d]\r\n", client->socket_num);break; // 如果发送失败,退出循环}debug_print("Sent %d bytes to client[%d]\r\n", sent_bytes, client->socket_num);vTaskDelay(1000 / portTICK_PERIOD_MS); // 延迟1秒}// 如果退出循环,释放客户端信息并删除任务mem_free(client);closesocket(client->socket_num);vTaskDelete(NULL);
}void tcp_server_thread(void *param){struct client_info* client = (struct client_info *)param;/* 某个客户端连接 */debug_print("Client[%d]%s:%d is connect server\r\n", client->socket_num, inet_ntoa(client->ip_addr.sin_addr),ntohs(client->ip_addr.sin_port));/* 向客户端发送连接成功信息 */send(client->socket_num, (const void* )send_data, strlen(send_data), 0);// 创建发送任务TaskHandle_t send_task_handle;xTaskCreate(send_task, "SendTask", 1024, (void *)client, osPriorityNormal, &send_task_handle);if (send_task_handle == NULL) {debug_print("Failed to create send task for client[%d]\r\n", client->socket_num);}while (1){char str[1024];memset(str, 0, sizeof(str));int bytes = recv(client->socket_num, str, sizeof(str), 0);/* 获取关闭连接的请求 */if (bytes <= 0){mem_free(client);closesocket(client->socket_num);break;}debug_print("[%d] %s:%d recv size:%d\r\n", client->socket_num, inet_ntoa(client->ip_addr.sin_addr),ntohs(client->ip_addr.sin_port), bytes);send((int )client->socket_num, (const void * )str, bytes, 0);}debug_print("[%d]%s:%d is disconnect...\r\n", client->socket_num, inet_ntoa(client->ip_addr.sin_addr),ntohs(client->ip_addr.sin_port));vTaskDelete(NULL); /* 删除该任务 */
}void tcp_server_init(void){int sin_size = sizeof(struct sockaddr_in);char client_name[10] = "server";char client_num[10];/* socket连接结构体申请内存 */socket_link_info = (struct link_socket_info *)mem_malloc(sizeof(struct link_socket_info));/* 设置客户端任务信息 */client_task_fo = (struct client_task_info *)mem_malloc(sizeof(struct client_task_info));client_task_fo->client_handler = NULL;client_task_fo->client_task_pro = osPriorityNormal;client_task_fo->client_task_stk = 1024;  //无法运行时增大栈内存/* 创建socket连接 */if((socket_link_info->sock_listen = socket(AF_INET, SOCK_STREAM, 0)) == -1){debug_print("Socket error\r\n");return;}/* 初始化连接的服务端地址 */socket_link_info->listen_addr.sin_family = AF_INET;socket_link_info->listen_addr.sin_port = htons(5000);socket_link_info->listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);memset(&(socket_link_info->listen_addr.sin_zero), 0, sizeof(socket_link_info->listen_addr.sin_zero));/* 绑定socket和连接的服务端地址信息 */if (bind(socket_link_info->sock_listen, (struct sockaddr * )&socket_link_info->listen_addr, sizeof(struct sockaddr)) < 0){debug_print("Bind fail!\r\n");goto __exit;}/* 监听客户端的数量 */listen(socket_link_info->sock_listen, 4);debug_print("begin listing...\r\n");while (1){/* 请求客户端连接 */socket_link_info->sock_connect = accept(socket_link_info->sock_listen, (struct sockaddr* )&socket_link_info->connect_addr, (socklen_t* )&sin_size);if (socket_link_info->sock_connect == -1){debug_print("no socket,waitting others socket disconnect.\r\n");continue;}lwip_itoa((char *)socket_link_info->sock_connect, (size_t)client_num, 10);strcat(client_name, client_num);client_task_fo->client_name = client_name;client_task_fo->client_num = client_num;/* 初始化连接客户端信息 */client_fo = (struct client_info *)mem_malloc(sizeof(struct client_info));client_fo->socket_num = socket_link_info->sock_connect;memcpy(&client_fo->ip_addr, &socket_link_info->connect_addr, sizeof(struct sockaddr_in));client_fo->sockaddr_len = sin_size;/* 创建连接的客户端任务 */xTaskCreate((TaskFunction_t )tcp_server_thread,  (const char *   )client_task_fo->client_name,(uint16_t       )client_task_fo->client_task_stk,(void *         )(void*) client_fo,(UBaseType_t    )client_task_fo->client_task_pro ++ ,(TaskHandle_t * )&client_task_fo->client_handler);if (client_task_fo->client_handler == NULL){debug_print("no memery for thread %s startup failed!\r\n",client_task_fo->client_name);mem_free(client_fo);continue;}else{debug_print("thread %s success!\r\n", client_task_fo->client_name);}}__exit: debug_print("listener failed\r\n");/* 关闭这个socket */closesocket(socket_link_info->sock_listen);vTaskDelete(NULL); /* 删除本任务 */
}} // lwip_tcp namespace end

头文件

/********************************************************************************* @file         lwip_tcp_driver.h* @brief   ******************************************************************************* @attention* @auther       by shiyongfu*******************************************************************************/
#ifndef LWIP_TCP_DRIVER_H
#define LWIP_TCP_DRIVER_H#include "stm32f4xx_hal.h"
#include "lwip/opt.h"
#include "lwip/sockets.h"#include "lwip/sys.h"
#include "lwip/api.h"namespace lwip_tcp{/* 客户端的信息 */struct client_info{int socket_num;                 /* socket号的数量 */struct sockaddr_in ip_addr;     /* socket客户端的IP地址 */int sockaddr_len;               /* socketaddr的长度 */};/* 客户端的任务信息 */struct client_task_info{UBaseType_t client_task_pro;    /* 客户端任务优先级 */uint16_t client_task_stk;       /* 客户端任务优先级 */TaskHandle_t * client_handler;  /* 客户端任务控制块 */char *client_name;              /* 客户端任务名称 */char *client_num;               /* 客户端任务数量 */};/* socket信息 */struct link_socket_info{int sock_listen;                /* 监听 */int sock_connect;               /* 连接 */struct sockaddr_in listen_addr; /* 监听地址 */struct sockaddr_in connect_addr;/* 连接地址 */};void tcp_server_init(void);void tcp_client_init(void);
}
#endif
http://www.lryc.cn/news/512694.html

相关文章:

  • 逆袭之路(11)——python网络爬虫:原理、应用、风险与应对策略
  • KOI技术-事件驱动编程(Sping后端)
  • LVS 负载均衡原理 | 配置示例
  • Hive分区再分桶表
  • 从 Coding (Jenkinsfile) 到 Docker:全流程自动化部署 Spring Boot 实战指南(简化篇)
  • Linux官文转载-- Linux 内核代码风格
  • Qt监控系统放大招/历经十几年迭代完善/多屏幕辅屏预览/多层级设备树/网络登录和回放
  • 【贪心算法】贪心算法七
  • LangChain教程 - 表达式语言 (LCEL) -构建智能链
  • 使用Locust对Redis进行负载测试
  • HIVE数据仓库分层
  • 数据结构与算法之动态规划: LeetCode 2407. 最长递增子序列 II (Ts版)
  • 电子电气架构 --- 什么是自动驾驶技术中的域控制单元(DCU)?
  • html5css3
  • FPGA多路红外相机视频拼接输出,提供2套工程源码和技术支持
  • python实战(十二)——如何进行新词发现?
  • 动手做计算机网络仿真实验入门学习
  • 完整的 FFmpeg 命令使用教程
  • Leetcode 3405. Count the Number of Arrays with K Matching Adjacent Elements
  • Springboot(五十六)SpringBoot3集成SkyWalking
  • 有没有免费提取音频的软件?音频编辑软件介绍!
  • Linux 中查看内存使用情况全攻略
  • 【SQL Server】教材数据库(3)
  • 使用 ECharts 与 Vue 构建数据可视化组件
  • Yocto 项目 - 共享状态缓存 (Shared State Cache) 机制
  • Unity3D仿星露谷物语开发9之创建农场Scene
  • STM32-笔记20-测量按键按下时间
  • 2024年12月30日Github流行趋势
  • SAP PP bom历史导出 ALV 及XLSX 带ECN号
  • 使用WebRTC进行视频通信