tcp_server example not able to reconnect the server after disconnect

axellin
Posts: 200
Joined: Mon Sep 17, 2018 9:09 am

tcp_server example not able to reconnect the server after disconnect

Postby axellin » Thu Oct 25, 2018 7:49 am

Testing with esp-idf master tree.

The test steps:
1. Connect to tcp server, send some characters then disconnect.
2. Try connect again always fails. (bind : errno 112)

Something wrong with the example code?

I (5188) event: sta ip: 192.168.0.100, mask: 255.255.255.0, gw: 192.168.0.1
I (5188) example: SYSTEM_EVENT_STA_GOT_IP
I (5188) example: Connected to AP
I (5198) example: Socket created
I (5198) example: Socket binded
I (5198) example: Socket listening
I (8608) example: Socket accepted
I (10958) example: Received 3 bytes from 192.168.0.104:
I (10958) example: aa

I (13418) example: Received 2 bytes from 192.168.0.104:
I (13418) example:

I (14948) example: Connection closed
E (14948) example: Shutting down socket and restarting...
I (14948) example: Socket created
E (14958) example: Socket unable to bind: errno 112

vtomix
Posts: 6
Joined: Mon Sep 10, 2018 8:25 pm

Re: tcp_server example not able to reconnect the server after disconnect

Postby vtomix » Sat Oct 27, 2018 7:28 pm

I just ran into this problem too. Do you have any solution? I tied with ethernet.

vtomix
Posts: 6
Joined: Mon Sep 10, 2018 8:25 pm

Re: tcp_server example not able to reconnect the server after disconnect

Postby vtomix » Sat Oct 27, 2018 8:37 pm

I solved it! Remove shutdown(sock, 0); line!

axellin
Posts: 200
Joined: Mon Sep 17, 2018 9:09 am

Re: tcp_server example not able to reconnect the server after disconnect

Postby axellin » Mon Oct 29, 2018 6:32 am

Remove shutdown(sock, 0); line does not work.
I still got E (8967) example: Socket unable to bind: errno 112

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

Re: tcp_server example not able to reconnect the server after disconnect

Postby ESP_Sprite » Tue Oct 30, 2018 4:22 am

Not sure how LWIP handles it, but in general in BSD socket layers, sockets will stay in SO_WAIT when closed, disallowing you to open a new socket at that port for a while. You should be able to use the socket option SO_REUSEADDR to get around this. (Note that this should be enabled in menuconfig, under component config -> lwip; I think it's normally on.)

axellin
Posts: 200
Joined: Mon Sep 17, 2018 9:09 am

Re: tcp_server example not able to reconnect the server after disconnect

Postby axellin » Wed Oct 31, 2018 12:56 am

Actually, I already tried setting SO_REUSEADDR, but still got the same error.
I'm sure LWIP_SO_REUSE=y.
I also tried adding below code to enable SO_REUSEADDR:
#if SO_REUSE
int opt = 1;
err = setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if (err != 0) {
ESP_LOGE(TAG, "Socket unable to set SO_REUSEADDR: errno %d", errno);
break;
}
#endif

Since it's an example code of esp-idf, I think you can easily test it.
Please make it work out-of-the-box. Many people reference the example code snips.

Thanks.

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

Re: tcp_server example not able to reconnect the server after disconnect

Postby ESP_Sprite » Wed Oct 31, 2018 3:51 am

What example specifically is this?

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: tcp_server example not able to reconnect the server after disconnect

Postby WiFive » Wed Oct 31, 2018 4:06 am

ESP_Sprite wrote:What example specifically is this?
https://github.com/espressif/esp-idf/tr ... tcp_server

mikemoy
Posts: 627
Joined: Fri Jan 12, 2018 9:10 pm

Re: tcp_server example not able to reconnect the server after disconnect

Postby mikemoy » Wed Oct 31, 2018 6:03 am

Move the

Code: Select all

while (1) {
just above

Code: Select all

err = listen(listen_sock, 1);
and comment out the 2 break statements above, youll have to deal with the break logic better, I just didn't have the time.
But this makes it work. You dont want to bind again, once you have already bound.
Looks like this.

Code: Select all

static void tcp_server_task(void *pvParameters)
{
    char rx_buffer[128];
    char addr_str[128];
    int addr_family;
    int ip_protocol;

  

#ifdef CONFIG_EXAMPLE_IPV4
        struct sockaddr_in destAddr;
        destAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        destAddr.sin_family = AF_INET;
        destAddr.sin_port = htons(PORT);
        addr_family = AF_INET;
        ip_protocol = IPPROTO_IP;
        inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1);
#else // IPV6
        struct sockaddr_in6 destAddr;
        bzero(&destAddr.sin6_addr.un, sizeof(destAddr.sin6_addr.un));
        destAddr.sin6_family = AF_INET6;
        destAddr.sin6_port = htons(PORT);
        addr_family = AF_INET6;
        ip_protocol = IPPROTO_IPV6;
        inet6_ntoa_r(destAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
#endif

        int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol);
        if (listen_sock < 0) {
            ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
            //break;
        }
        ESP_LOGI(TAG, "Socket created");

        int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
        if (err != 0) {
            ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno);
            //break;
        }
        ESP_LOGI(TAG, "Socket binded");

  while (1) {

        err = listen(listen_sock, 1);
        if (err != 0) {
            ESP_LOGE(TAG, "Error occured during listen: errno %d", errno);
            break;
        }
        ESP_LOGI(TAG, "Socket listening");

axellin
Posts: 200
Joined: Mon Sep 17, 2018 9:09 am

Re: tcp_server example not able to reconnect the server after disconnect

Postby axellin » Wed Oct 31, 2018 6:23 am

Hi mikemoy,
It looks fine now after apply the changes you mentioned.
Thanks a lot.

Who is online

Users browsing this forum: No registered users and 97 guests