IDF V5.0 TCP Socket Client Memory Leak
Posted: Mon Jan 30, 2023 12:00 pm
Hi,
In IDF V5.0, When I create this task more than 1, my heap starts to leak dramatically.
In IDF V4.4 there is no such leak. Works great.
My purpose;
create socket->do job->close socket;
but it should be asynchronous.
I am ready to provide more information if you need it, but it is very easy to create the same problem.
Best Regards,
Halil ARIKEL
In IDF V5.0, When I create this task more than 1, my heap starts to leak dramatically.
In IDF V4.4 there is no such leak. Works great.
My purpose;
create socket->do job->close socket;
but it should be asynchronous.
- typedef struct
- {
- int tv_sec;
- int tv_usec;
- }timeval_t;
- #define HOST_IP_ADDR "192.168.215.111"
- #define PORT 3333
- char payload[20];
- static void tcp_client_task(void* pvParameters)
- {
- char* TAG = calloc(1, 20 * sizeof(char));
- memcpy(TAG, (char*)pvParameters, 20 * sizeof(char));
- char rx_buffer[128];
- char host_ip[] = HOST_IP_ADDR;
- int addr_family = 0;
- int ip_protocol = 0;
- timeval_t timeout;
- int sendload = 1;
- int err;
- int sock;
- struct sockaddr_in dest_addr;
- struct linger linger;
- int len;
- //vTaskDelay(5000 / portTICK_PERIOD_MS);
- while (1) {
- ESP_LOGW(TAG, "free_heap:%ld, min_free_heap:%ld", esp_get_free_heap_size(), esp_get_minimum_free_heap_size());
- dest_addr.sin_addr.s_addr = inet_addr(host_ip);
- dest_addr.sin_family = AF_INET;
- dest_addr.sin_port = htons(PORT);
- addr_family = AF_INET;
- ip_protocol = IPPROTO_IP;
- sock = socket(addr_family, SOCK_STREAM, ip_protocol);
- if (sock < 0) {
- ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
- continue;
- }
- ESP_LOGI(TAG, "Socket created, connecting to %s:%d", host_ip, PORT);
- timeout.tv_sec = 0;
- timeout.tv_usec = 100000;
- setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeval_t));
- linger.l_onoff = 1;
- linger.l_linger = 0;
- if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) == 0) {
- ESP_LOGI(TAG, "Set SO_LINGER success");
- }
- err = connect(sock, (struct sockaddr*)&dest_addr, sizeof(struct sockaddr_in));
- if (err != 0) {
- ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
- goto TEST;
- }
- ESP_LOGI(TAG, "%d Successfully connected", sock);
- sendload++;
- sprintf(&payload, ":%d", sendload);
- err = send(sock, payload, strlen(payload), MSG_DONTWAIT);
- if (err < 0) {
- ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
- goto TEST;
- }
- len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, MSG_DONTWAIT);
- // Error occurred during receiving
- if (len < 0) {
- ESP_LOGE(TAG, "recv failed: errno %d", errno);
- }
- // Data received
- else {
- rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
- ESP_LOGI(TAG, "Received %d bytes from %s:", len, host_ip);
- ESP_LOGI(TAG, "%s", rx_buffer);
- }
- ESP_LOGE(TAG, "%d Shutting down socket and restarting...",sock);
- TEST:
- shutdown(sock, 0);
- close(sock);
- }
- vTaskDelete(NULL);
- }
- void app_main(void)
- {
- ESP_ERROR_CHECK(nvs_flash_init());
- ESP_ERROR_CHECK(esp_netif_init());
- ESP_ERROR_CHECK(esp_event_loop_create_default());
- /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
- * Read "Establishing Wi-Fi or Ethernet Connection" section in
- * examples/protocols/README.md for more information about this function.
- */
- ESP_ERROR_CHECK(example_connect());
- xTaskCreate(tcp_client_task, "tcp_client_task4", 1024 * 8, "4", 5, NULL);
- xTaskCreate(tcp_client_task, "tcp_client_task3", 1024 * 8, "3", 5, NULL);
- xTaskCreate(tcp_client_task, "tcp_client_task2", 1024 * 8, "2", 5, NULL);
- xTaskCreate(tcp_client_task, "tcp_client_task1", 1024 * 8, "1", 5, NULL);
- }
Best Regards,
Halil ARIKEL