ESP32-C3, esp-idf 4.3.5,tcp client 非阻塞式循环收发
时间: 2023-08-24 07:06:21 浏览: 168
你可以使用 ESP-IDF 中提供的 FreeRTOS API 和 LWIP API 来实现 ESP32-C3 上的非阻塞式 TCP client。以下是一个简单的实现示例:
```c
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "lwip/err.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/api.h"
static const char *TAG = "tcp_client";
void tcp_client_task(void *pvParameters)
{
const char *server_ip = "192.168.1.100";
const int server_port = 12345;
struct sockaddr_in dest_addr;
dest_addr.sin_addr.s_addr = inet_addr(server_ip);
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(server_port);
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
ESP_LOGE(TAG, "Failed to create socket");
vTaskDelete(NULL);
}
// Set socket to non-blocking mode
int flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
// Connect to server
int ret = connect(sockfd, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
if (ret < 0 && errno != EINPROGRESS) {
ESP_LOGE(TAG, "Failed to connect to server");
vTaskDelete(NULL);
}
// Wait for connection to complete
fd_set write_fds;
FD_ZERO(&write_fds);
FD_SET(sockfd, &write_fds);
ret = select(sockfd + 1, NULL, &write_fds, NULL, NULL);
if (ret < 0) {
ESP_LOGE(TAG, "Failed to wait for connection to complete");
vTaskDelete(NULL);
}
// Check if connection was successful
int error = 0;
socklen_t error_len = sizeof(error);
getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &error_len);
if (error != 0) {
ESP_LOGE(TAG, "Failed to connect to server: %d", error);
vTaskDelete(NULL);
}
ESP_LOGI(TAG, "Connected to server");
char rx_buffer[128];
while (1) {
// Receive data
int len = recv(sockfd, rx_buffer, sizeof(rx_buffer), 0);
if (len < 0 && errno != EAGAIN) {
ESP_LOGE(TAG, "Failed to receive data");
break;
} else if (len > 0) {
ESP_LOGI(TAG, "Received %d bytes: %.*s", len, len, rx_buffer);
}
// Send data
const char *tx_buffer = "Hello, server!";
len = send(sockfd, tx_buffer, strlen(tx_buffer), MSG_DONTWAIT);
if (len < 0 && errno != EAGAIN) {
ESP_LOGE(TAG, "Failed to send data");
break;
} else if (len > 0) {
ESP_LOGI(TAG, "Sent %d bytes: %s", len, tx_buffer);
}
vTaskDelay(pdMS_TO_TICKS(1000));
}
close(sockfd);
vTaskDelete(NULL);
}
void app_main()
{
xTaskCreate(tcp_client_task, "tcp_client_task", 4096, NULL, 5, NULL);
}
```
在这个示例中,我们首先创建了一个非阻塞式的 socket,并设置其连接状态为非阻塞式。在连接服务器时,我们使用了 `select()` 函数来等待连接完成。在主循环中,我们使用 `recv()` 函数接收数据,并使用 `send()` 函数发送数据。注意,在发送数据时,我们使用了 `MSG_DONTWAIT` 标志来确保数据发送不会阻塞。
阅读全文