当前位置: 首页 > 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.mrgr.cn/news/82056.html

相关文章:

  • 开发小工具:ping地址
  • Go 语言 API 限流实战:保障系统稳定性的护盾
  • Spring Boot 各种事务操作实战(自动回滚、手动回滚、部分回滚)
  • (二)当人工智能是一个函数,函数形式怎么选择?ChatGPT的函数又是什么?
  • 【Rust自学】8.4. String类型 Pt.2:字节、标量值、字形簇以及字符串的各类操作
  • 基于ssm企业台账管理平台源码和答辩PPT论文
  • 大模型WebUI:Gradio全解系列8——Additional Features:补充特性(上)
  • 小米路由器开启SSH,配置阿里云ddns,开启外网访问SSH和WEB管理界面
  • Isaac Sim Docker 中使用 Python 脚本
  • 一份关于 Ubuntu 系统下代理配置的故障排查笔记
  • Linux高并发服务器开发 第七天(静态库 动态库)
  • LVS 负载均衡原理 | 配置示例
  • Linux高级--3.2.4.2 常见的几种timer的设计方案
  • Java基本操作笔记
  • 协程原理 函数栈 有栈协程
  • 有限元分析学习——Anasys Workbanch第一阶段笔记(2)应力奇异及位移结果对比、初步了解单元的基本知识
  • 大数据组件(一)快速入门调度组件Airflow
  • 人形机器人全身运动规划相关资料与文章
  • PaddleOCROCR关键信息抽取训练过程
  • 蓝桥杯(Java)(ing)
  • 【网络安全实验室】基础关实战详情
  • 沪深捉妖记(一)探寻妖股的特征
  • 数据结构与算法之动态规划: LeetCode 3105. 最长的严格递增或递减子数组 (Ts版)
  • Nginx - 整合lua 实现对POST请求的参数拦截校验(不使用Openresty)
  • L25.【LeetCode笔记】 三步问题的四种解法(含矩阵精彩解法!)
  • SAP SD信贷管理信用管理手册(下)