Simple socket and errno = 11, No more processes

FrankJensen
Posts: 35
Joined: Sun Mar 10, 2024 9:34 pm

Simple socket and errno = 11, No more processes

Postby FrankJensen » Sun Mar 10, 2024 9:55 pm

Hi forum. New here. I have programmed many years in the Arduino framework and have now switched to ESP-IDF. Platformio. But I am struggling for some days, getting a simple socket to work. No matter what I try, I can not get a response from my server. I know for sure, that the server sends a reply. The Arduino code also worked flawlessly.

My log says:
- Successfully connected
- Data sent successfully
- Failed to receive data: 11 - No more processes

It fails after the timeout. If I do not have the timeout, recv hangs forever.

This code runs in a separate thread. I have boiled down the code to this.
Any suggestions would be apreciated :roll:

I should mention, that I have also a webserver and a httpClient running.
But there should be plenty of resources.
I only send 12 bytes of data, and the reply is less than 100 bytes.
  1.  
  2.         struct sockaddr_in dest_addr;
  3.         inet_pton(AF_INET, host_ip, &dest_addr.sin_addr);
  4.         dest_addr.sin_family = AF_INET;
  5.         dest_addr.sin_port = htons(PORT);
  6.         addr_family = AF_INET;
  7.         ip_protocol = IPPROTO_IP;
  8.  
  9.         int sock = socket(addr_family, SOCK_STREAM, ip_protocol);
  10.         if (sock < 0)
  11.         {
  12.             ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
  13.             break;
  14.         }
  15.         ESP_LOGI(TAG, "Socket created ");
  16.         ESP_LOGI(TAG, "Connecting to %s:%d", host_ip, PORT);
  17.  
  18.         int err = connect(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
  19.         if (err != 0)
  20.         {
  21.             ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
  22.             break;
  23.         }
  24.         ESP_LOGI(TAG, "Successfully connected");
  25.  
  26.         int nSend = send(sock, sendbuffer, _len_trans, 0);
  27.  
  28.          if (nSend < 0) {
  29.                 ESP_LOGE(TAG, "Failed to send data");
  30.         }
  31.         else {
  32.              ESP_LOGI(TAG, "Data sent successfully");
  33.         }
  34.  
  35. // Set timeout for recv function
  36.          struct timeval timeout;
  37.          timeout.tv_sec = 5; // 5 second timeout
  38.          timeout.tv_usec = 0;
  39.          if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
  40.               ESP_LOGE(TAG, "Failed to set socket receive timeout");
  41.         }
  42.  
  43.          int bytes_received = recv(sock, _frame, _len_recv, 0);
  44.  
  45.         if (bytes_received < 0) {
  46.                ESP_LOGE(TAG, "Failed to receive data: %i - %s", errno, strerror(errno));
  47.         }
  48.         if (bytes_received == 0) {
  49.               ESP_LOGI(TAG, "Server closed connection");
  50.        }
  51.        if (bytes_received > 0) {
  52.            ESP_LOGI(TAG, "Data received successfully");
  53.        }
  54.  
  55.         if (sock != -1)
  56.         {
  57.             shutdown(sock, 0);
  58.             close(sock);
  59.         }
  60.  

ESP_Sprite
Posts: 9052
Joined: Thu Nov 26, 2015 4:08 am

Re: Simple socket and errno = 11, No more processes

Postby ESP_Sprite » Mon Mar 11, 2024 3:48 am

Hm, I've been staring at your code for a while, but I'm not seeing the issue; it looks perfectly cromulent to me.

chegewara
Posts: 2240
Joined: Wed Jun 14, 2017 9:00 pm

Re: Simple socket and errno = 11, No more processes

Postby chegewara » Mon Mar 11, 2024 5:46 am

Maybe try w/o this code?
struct timeval timeout;
timeout.tv_sec = 5; // 5 second timeout
timeout.tv_usec = 0;
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
ESP_LOGE(TAG, "Failed to set socket receive timeout");
}

FrankJensen
Posts: 35
Joined: Sun Mar 10, 2024 9:34 pm

Re: Simple socket and errno = 11, No more processes

Postby FrankJensen » Mon Mar 11, 2024 7:27 am

Hi chegewara.

I did try without that code, and then recv never returns.

I have also tried:
- using write instead of send (not sure what the difference)
- polling the socket before recv to make sure its available (it times out).

My webserver and httpclient is running perfectly. But when this code is enabled, after 5-10 minutes, there are no available sockets, so both webserver and httpclient hangs. So somehow its eating up sockets, even though I make sure to close every time.

When I upload my old Arduino code, it just connects, and run immediately. So the server is running.

And just now, I have tried not to start the webserver and the httpclient. This changes nothing. Maybe I should try and port this code to a complete fresh project, to see if the problem persists.....

My log looks like this (I send every 10 seconds).
*****TRYINGI (26706) Huawei: Data sent successfully
Length: 12 - 00 00 00 00 00 06 01 03 75 30 00 23
BeforeReceived: -1E (31706) Huawei: Failed to receive data: 11 - No more processes
*****TRYINGI (36706) Huawei: Data sent successfully
Length: 12 - 00 00 00 00 00 06 01 03 75 30 00 23
BeforeReceived: -1E (36756) Huawei: Failed to receive data: 104 - Connection reset by peer
**********TRYINGI (46756) Huawei: Data sent successfully
Length: 12 - 00 00 00 00 00 06 01 03 75 30 00 23
BeforeReceived: -1E (51756) Huawei: Failed to receive data: 11 - No more processes
******TRYINGI (57756) Huawei: Data sent successfully
Length: 12 - 00 00 00 00 00 06 01 03 75 30 00 23
BeforeReceived: -1E (62756) Huawei: Failed to receive data: 11 - No more processes
******TRYINGI (68756) Huawei: Data sent successfully
Length: 12 - 00 00 00 00 00 06 01 03 75 30 00 23
BeforeReceived: -1E (73766) Huawei: Failed to receive data: 11 - No more processes
*****TRYINGI (78766) Huawei: Data sent successfully
Length: 12 - 00 00 00 00 00 06 01 03 75 30 00 23
BeforeReceived: -1E (83766) Huawei: Failed to receive data: 11 - No more processes
******TRYINGI (89766) Huawei: Data sent successfully
Length: 12 - 00 00 00 00 00 06 01 03 75 30 00 23
BeforeReceived: -1E (94766) Huawei: Failed to receive data: 11 - No more processes
******TRYINGI (100766) Huawei: Data sent successfully
Length: 12 - 00 00 00 00 00 06 01 03 75 30 00 23
BeforeReceived: -1E (105766) Huawei: Failed to receive data: 11 - No more processes
******TRYINGI (111776) Huawei: Data sent successfully
Length: 12 - 00 00 00 00 00 06 01 03 75 30 00 23
BeforeReceived: -1E (116776) Huawei: Failed to receive data: 11 - No more processes
*****TRYINGI (121776) Huawei: Data sent successfully

FrankJensen
Posts: 35
Joined: Sun Mar 10, 2024 9:34 pm

Re: Simple socket and errno = 11, No more processes

Postby FrankJensen » Mon Mar 11, 2024 7:59 am

And even with all other webservices disables, after aprox 10 minutes

*TRYINGE (1619426) Huawei: Connection failed
*TRYINGE (1638926) Huawei: Connection failed
*TRYINGE (1658426) Huawei: Connection failed
*TRYINGE (1681426) Huawei: Connection failed
*TRYINGE (1741426) Huawei: Connection failed
*TRYINGE (1801426) Huawei: Connection failed
*TRYINGE (1861426) Huawei: Connection failed
*TRYINGE (1921426) Huawei: Connection failed
*TRYINGE (1981426) Huawei: Connection failed
*TRYINGE (2041426) Huawei: Connection failed

ESP_Sprite
Posts: 9052
Joined: Thu Nov 26, 2015 4:08 am

Re: Simple socket and errno = 11, No more processes

Postby ESP_Sprite » Mon Mar 11, 2024 8:44 am

In that particular case, the issue may be lingering sockets. Sockets will stay in TIME_WAIT for a while after you close them; if you have too many of those (by making and closing many connections within a small amount of time), you might not be able to create more.

chegewara
Posts: 2240
Joined: Wed Jun 14, 2017 9:00 pm

Re: Simple socket and errno = 11, No more processes

Postby chegewara » Mon Mar 11, 2024 1:00 pm

Hi,
thats exactly the reason i asked you to remove this part of code.
The OP is suggesting its happening on first iteration with socket server, but its happening after some time.
Like mr Sprite said, you are exhausting sockets (on server) which you can see here

Code: Select all

Huawei: Failed to receive data: 104 - Connection reset by peer
Please try to add this, not sure if it helps thou

Code: Select all

    int opt = 1;
    setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
or close socket always when you return from the code you posted

FrankJensen
Posts: 35
Joined: Sun Mar 10, 2024 9:34 pm

Re: Simple socket and errno = 11, No more processes

Postby FrankJensen » Mon Mar 11, 2024 1:34 pm

When I remove the timeout block, recv never returns.

Log says:
*******TRYINGI (16661) Huawei: Data sent successfully
Length: 12 - 00 00 00 00 00 06 01 03 75 30 00 23
Before


Then this thread hangs forever. It never passes the recv line. Before I sprintf in the line before recv. And the line right after recv, should be Received

Adding the SO_REUSEADDR right after creating the socket, makes no difference, thread hangs in recv.

Adding the timeout back in, still with the SO_REUSEADDR, gives same result as before - however I have not checked if it has stopped eating sockets, I am checking right now.

The Reset by peer error, I have actually only seen this one time, where I made the post. Normally it always return error 11, No more processes.

MicroController
Posts: 1218
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Simple socket and errno = 11, No more processes

Postby MicroController » Mon Mar 11, 2024 9:25 pm

Code: Select all

ESP_LOGI(TAG, "Data sent successfully");
is not quite accurate ;-)
At this point, the data is not sent successfully but placed into the IP stack's buffer. Normally that's not much of a difference, but if you look into the lwIP configuration in menuconfig you may find that, by default, lwIP is set to retry sending a packet ('segment') every 60 seconds ("maximum segment lifetime") up to 12 times before giving up. So if for some reason your data doesn't make it to the other end and/or the ACK is never received, you 1) will not know for about 12 minutes and 2) will have a 'zombie' socket for that period, or until you close it.

TL;DR: The data you send apparently never makes it to the other end, and hence the other end never responds.
Last edited by MicroController on Mon Mar 11, 2024 9:34 pm, edited 2 times in total.

FrankJensen
Posts: 35
Joined: Sun Mar 10, 2024 9:34 pm

Re: Simple socket and errno = 11, No more processes

Postby FrankJensen » Mon Mar 11, 2024 9:32 pm

OK, thats some usefull information. So even though the send responds with the correct amount of bytes, it only means that they have been delivered to the buffer. How can I find out, why its not sent?

How can I send it? Do I somehow need to flush it?

Since the Arduino version is working, I dont expect it to be a server nor a reply problem. But if the data is never sent, of course there is no reply...

Who is online

Users browsing this forum: MicroController and 221 guests