ESP32-C3, esp-idf 4.3.5,tcp client 非阻塞式循环收发,提供一个例程
时间: 2024-01-01 08:10:36 浏览: 174
好的,以下是基于 ESP32-C3 和 esp-idf 4.3.5 的 TCP 客户端非阻塞式循环收发的示例代码:
```c
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_netif.h"
#include "esp_tls.h"
#include "lwip/err.h"
#include "lwip/sys.h"
#include "lwip/sockets.h"
#define WIFI_SSID "your_wifi_ssid"
#define WIFI_PASS "your_wifi_password"
#define SERVER_IP "server_ip_address"
#define SERVER_PORT 12345
static const char *TAG = "tcp_client";
static void wifi_init_sta(void)
{
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&cfg);
esp_wifi_set_mode(WIFI_MODE_STA);
wifi_config_t wifi_config = {
.sta = {
.ssid = WIFI_SSID,
.password = WIFI_PASS,
},
};
esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
esp_wifi_start();
}
void tcp_client_task(void *pvParameters)
{
char rx_buffer[128];
char addr_str[128];
int addr_family;
int ip_protocol;
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);
addr_family = AF_INET;
ip_protocol = IPPROTO_IP;
inet_ntoa_r(dest_addr.sin_addr, addr_str, sizeof(addr_str) - 1);
int sock = socket(addr_family, SOCK_STREAM, ip_protocol);
if (sock < 0) {
ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
vTaskDelete(NULL);
return;
}
ESP_LOGI(TAG, "Socket created, connecting to %s:%d", SERVER_IP, SERVER_PORT);
if (connect(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) != 0) {
ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
close(sock);
vTaskDelete(NULL);
return;
}
ESP_LOGI(TAG, "Successfully connected");
while (1) {
int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
if (len < 0) {
ESP_LOGE(TAG, "Error occurred during receiving: errno %d", errno);
break;
} else if (len == 0) {
ESP_LOGW(TAG, "Connection closed");
break;
} else {
rx_buffer[len] = '\0';
ESP_LOGI(TAG, "Received %d bytes: %s", len, rx_buffer);
}
int err = send(sock, "Hello Server!", strlen("Hello Server!"), 0);
if (err < 0) {
ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
break;
}
ESP_LOGI(TAG, "Message sent");
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
if (sock != -1) {
ESP_LOGE(TAG, "Shutting down socket and restarting...");
shutdown(sock, SHUT_RDWR);
close(sock);
}
vTaskDelete(NULL);
}
void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
esp_netif_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
wifi_init_sta();
xTaskCreate(tcp_client_task, "tcp_client_task", 4096, NULL, 5, NULL);
}
```
在这个示例代码中,我们创建了一个 TCP 客户端,连接到指定的服务器 IP 地址和端口。在循环中,我们通过 `recv` 函数接收服务器发送的数据,并通过 `send` 函数发送数据到服务器。需要注意的是,这两个函数都是非阻塞式的,因此任务可以在等待数据时执行其他操作。
在 `app_main` 函数中,我们初始化了 Wi-Fi 并创建了我们的 TCP 客户端任务。
请记得将示例代码中的 `WIFI_SSID`、`WIFI_PASS`、`SERVER_IP` 和 `SERVER_PORT` 替换为你的实际值。
希望这个示例代码对你有所帮助!
阅读全文