【STM32】 LWIP -TCP 客户端收发数据

TCP 客户端收发数据,使用 FreeRTOS(CMSIS-RTOS V2),并兼容嵌入式环境(如 STM32 + LWIP)。

🔧 1. 头文件:tcp_client.h

c 复制代码
#ifndef TCP_CLIENT_H
#define TCP_CLIENT_H

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

#define TCP_SERVER_IP     "192.168.1.100"
#define TCP_SERVER_PORT   8080

extern int g_client_sock;
extern bool g_socket_connected;
extern char tcpClientRxBuffer[512];

void startTcpClient(void *argument);
void tcpSendData(const char *data, size_t len);

#endif

📂 2. 源文件:tcp_client.c

c 复制代码
#include "tcp_client.h"
#include "cmsis_os2.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

int g_client_sock = -1;
bool g_socket_connected = false;
char tcpClientRxBuffer[512];

void startTcpClient(void *argument)
{
    struct sockaddr_in server_addr;

    while (1) {
        g_client_sock = socket(AF_INET, SOCK_STREAM, 0);
        if (g_client_sock < 0) {
            printf("Socket creation failed: %d (%s)\n", errno, strerror(errno));
            osDelay(2000);
            continue;
        }

        memset(&server_addr, 0, sizeof(server_addr));
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(TCP_SERVER_PORT);

        if (inet_pton(AF_INET, TCP_SERVER_IP, &server_addr.sin_addr) <= 0) {
            printf("Invalid server IP\n");
            close(g_client_sock);
            g_client_sock = -1;
            osDelay(2000);
            continue;
        }

        printf("Connecting to %s:%d...\n", TCP_SERVER_IP, TCP_SERVER_PORT);
        if (connect(g_client_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
            printf("Connect failed: %d (%s)\n", errno, strerror(errno));
            close(g_client_sock);
            g_client_sock = -1;
            osDelay(2000);
            continue;
        }

        g_socket_connected = true;
        printf("Connected to TCP server!\n");

        while (1) {
            int ret = recv(g_client_sock, tcpClientRxBuffer, sizeof(tcpClientRxBuffer) - 1, MSG_DONTWAIT);
            if (ret > 0) {
                tcpClientRxBuffer[ret] = '\0';
                printf("Received: %s\n", tcpClientRxBuffer);
            } else if (ret == 0) {
                printf("Server closed connection\n");
                break;
            } else {
                if (errno != EAGAIN && errno != EWOULDBLOCK) {
                    printf("Recv error: %d (%s)\n", errno, strerror(errno));
                    break;
                }
            }

            osDelay(2);
        }

        close(g_client_sock);
        g_client_sock = -1;
        g_socket_connected = false;
        printf("Disconnected, retrying...\n");
        osDelay(3000);
    }
}

void tcpSendData(const char *data, size_t len)
{
    static uint8_t notConnectCounter = 0;

    if (g_socket_connected) {
        if (g_client_sock < 0) {
            notConnectCounter++;
            osDelay(50);
            if (notConnectCounter > 100) {
                g_socket_connected = false;
                notConnectCounter = 0;
            }
            return;
        }

        int sent = send(g_client_sock, data, len, 0);
        if (sent < 0) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                printf("Send buffer full, retrying...\n");
            } else {
                printf("Send failed: %d (%s)\n", errno, strerror(errno));
                close(g_client_sock);
                g_client_sock = -1;
                g_socket_connected = false;
            }
        }

    } else {
        notConnectCounter++;
        if (notConnectCounter > 100) {
            notConnectCounter = 0;
            printf("Socket not connected\n");
        }
        osDelay(50);
    }
}

⚙️ 3. FreeRTOS 任务创建:main.c 示例

c 复制代码
#include "cmsis_os2.h"
#include "tcp_client.h"

void app_main(void *argument) {
    while (1) {
        if (g_socket_connected) {
            tcpSendData("Hello Server!\n", strlen("Hello Server!\n"));
        }
        osDelay(1000);
    }
}

int main(void)
{
    // 硬件和网络初始化...

    osKernelInitialize();
    osThreadNew(startTcpClient, NULL, NULL);
    osThreadNew(app_main, NULL, NULL);
    osKernelStart();

    while (1); // 不应该到达这里
}
相关推荐
枷锁—sha6 分钟前
【SRC】SQL注入WAF 绕过应对策略(二)
网络·数据库·python·sql·安全·网络安全
Zach_yuan43 分钟前
深入浅出 JSONCpp
linux·服务器·网络·c++
宵时待雨1 小时前
STM32笔记归纳9:定时器
笔记·stm32·单片机·嵌入式硬件
逐步前行1 小时前
STM32_新建工程(寄存器版)
stm32·单片机·嵌入式硬件
bai5459362 小时前
STM32 CubeIDE 通过PWM占空比控制舵机角度
stm32·单片机·嵌入式硬件
迎仔2 小时前
B-算力中心网络隔离的必要性:为什么必须隔离?
网络
野指针YZZ3 小时前
一键配置RK3588网络与SSH远程连接
网络·ssh·rk3588
迎仔4 小时前
10-网络安全监控与事件响应:数字世界的智能监控与应急系统
网络·安全·web安全
上海合宙LuatOS4 小时前
LuatOS核心库API——【audio 】
java·网络·单片机·嵌入式硬件·物联网·音视频·硬件工程
深圳市恒星物联科技有限公司5 小时前
水质流量监测仪:复合指标监测的管网智能感知设备
大数据·网络·人工智能