添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
读研的作业本  ·  Your request has been ...·  1 周前    · 
仗义的夕阳  ·  Solved: QSslSocket ...·  1 年前    · 
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:

Code: Select all

for (;;)
    fd_set read_fds;
    memcpy(&read_fds, &current_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, &current_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, &current_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
slompf wrote:
Mon Nov 11, 2019 12:40 pm
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.