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);
}