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

发布于:2025-06-19 ⋅ 阅读:(12) ⋅ 点赞:(0)
TCP 客户端收发数据,使用 FreeRTOS(CMSIS-RTOS V2),并兼容嵌入式环境(如 STM32 + LWIP)。

🔧 1. 头文件:tcp_client.h

#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

#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 示例

#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); // 不应该到达这里
}

网站公告

今日签到

点亮在社区的每一天
去签到