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

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 memset

static 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.kler.cn/a/460149.html

相关文章:

  • 【51项目】51单片机自制小霸王游戏机
  • vue2+echarts实现水球+外层动效
  • 鸿蒙DevEco Studio 5.0.1 Release下载npm镜像无法连接下载的解决方式:镜像地址变更为淘宝的npm 镜像,可解决
  • 移动端如何实现上拉加载
  • SAKO搜索帮助增强(FB02科目搜索帮助)
  • 智能家居体验大变革 博联 AI 方案让智能不再繁琐
  • 通用工具类与异常处理:Python实用指南
  • #Vue3篇: 无感刷新token的原理JSESSIONID无感刷新和JWT接口刷新
  • 算力股开盘大涨,电光科技7连板
  • C#中通过Mapster实现轻量级高效对象映射器
  • 【Leetcode 热题 100】39. 组合总和
  • Excel 面试 04 查找函数 XLOOKUP
  • leetcode------mysql
  • 【Lua】元表与元方法
  • 【论文阅读笔记】IceNet算法与代码 | 低照度图像增强 | IEEE | 2021.12.25
  • 我是用git pull每次都要输入账号密码
  • 数据安全技巧:使用私钥认证结合内网穿透实现安全高效的服务器管理
  • 应用层2——FTP文件传输协议
  • QT作业4
  • 一文大白话讲清楚CSS元素的水平居中和垂直居中
  • 浅显易懂的 git 入门
  • 电池放电仪在各领域的作用
  • android——屏幕适配
  • 【Flink运行时架构】系统构架
  • 咚次游戏加速1.1.4.2 | 免费PC游戏加速器,支持1473款游戏加速
  • 如何初始化css样式?为什么要初始化css?