I'm using lwip to receive data from a remote host. This works fine, but sometimes the connection goes down, so lwip_read returns -1 (error 113, Software caused connection abort). If this happens, I'm closing the socket I read.
After this happens sometimes, accept returns -1 (error 23, Too many open files in system).
Now I'm wondering, what to do to avoid the error of accept. What else but closing the socket can I do?
In order to make clearer what I'm doing, I striped down the logic into this pseudo code:
for (;;)
fd_set read_fds;
memcpy(&read_fds, ¤t_fds, sizeof(read_fds));
int triggered_nfds = select(highest_socket + 1, &read_fds, NULL, NULL, &timeout);
if (triggered_nfds > 0) // more than zero sockets have data
if (FD_ISSET(listen_socket, &read_fds)) // check if listener socket has data
int socket = accept(listen_socket, (struct sockaddr *)NULL, (socklen_t *)NULL);
if (socket < 0)
// log error
break;
// set:
/* 10 second timeout */
/* enable sending keepalive probes for socket */
/* 180 sec idle before start sending probes */
/* 30 sec between probes */
/* Drop connection after 4 probes without response */
FD_SET(socket, ¤t_fds);
// save connection
triggered_nfds--;
for (each accepted connection)
if (FD_ISSET(connection_socket, &read_fds))
int recv_size = lwip_read(connection_socket, buffer, buffer_size);
if(recv_size < 0)
// log error
FD_CLR(connection_socket, ¤t_fds); // clear socket in buffer
lwip_close(connection_socket);
}else{
// do sth with buffer
triggered_nfds--;
Thanks for your help,
Torsten
Hi Torsten,
LWIP has a limit of the maximum number of sockets in the system. ENFILE (23) will be returned if this limit is reached:
https://docs.espressif.com/projects/esp ... ax-sockets
The solution may be to either increase this limit in the project config, or fix a socket leak if you're not closing all the accept()-ed sockets - it's hard to see from the pseudocode if they will always be closed.
but in general, calling lwip_close after recv returned -1 should be enough to close the socket?
Thanks for your answer,
Torsten
but in general, calling lwip_close after recv returned -1 should be enough to close the socket?
Yes, this will close the socket at the ESP32 end. Of course, it only works if recv returns -1 first (ie the other end has closed the socket and isn't holding it open, or some packet loss meant the RST packet was not received yet, etc.)
In case you are using ESP-IDF v3.3 (or prior) release then `lwip_close` won't actually free up socket pcb, you have to use thread safe counterpart API `lwip_close_r` assuming you are using default configuration (
https://github.com/espressif/esp-lwip/b ... ets.c#L877
).
Ideally you can modify application to use POSIX APIs (i.e. `close` for `lwip_close` and so on), VFS layer in ESP-IDF will do correct translation as provided at
https://github.com/espressif/esp-idf/bl ... lwip.c#L61
and thus ensuring appropriate behaviour.