Сеть ESP32: Не удается отправить ответ TCP без потери соединения с сокетом - PullRequest
1 голос
/ 05 января 2020

Утро! Так что я довольно плохо знаком с сетевыми вещами и думаю, что немного перегружен. Я тоже очень плохо разбираюсь в заголовках, думаю, я не теряю соединение при отправке материала, но раньше, и просто выдает ошибку, когда пытаюсь это сделать.

Итак, вот моя проблема: на моей плате ESP32 Я настраиваю прослушиватель TCP (см. Ниже). Я создаю и привязываю сокет, а затем жду входящих соединений. Сценарий python на моем ноутбуке будет затем подключаться и отправлять TCP-пакет с некоторым содержимым, которое затем обрабатывает моя плата: а) оставляя общий WiFi, б) подключение к новому, где некоторые вещи выполняются, включая открытие и закрытие UDP-соединение, c) снова подключается к первому Wi-Fi, чтобы затем отправить ответ обратно на мой ноутбук.

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

    struct sockaddr_in dest_addr;
    dest_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(TCP_PORT);
    addr_family = AF_INET;
    ip_protocol = IPPROTO_IP;
    inet_ntoa_r(dest_addr.sin_addr, addr_str, sizeof(addr_str) - 1);

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

    else
    {
        ESP_LOGI(TAG, "Socket created");

        int err = bind(listen_sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
        if (err != 0) 
        {
            ESP_LOGE(TAG, "Unable to bind socket: errno %d", errno);
        }

        else
        {
            ESP_LOGI(TAG, "Socket bound, port %d", TCP_PORT);

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

                struct sockaddr_in6 source_addr;
                uint addr_len = sizeof(source_addr);
                int sock = accept(listen_sock, (struct sockaddr *)&source_addr, &addr_len);
                if (sock < 0) 
                {
                    ESP_LOGE(TAG, "Unable to accept connection: errno %d", errno);
                    break;
                }
                ESP_LOGI(TAG, "Connection accepted");

                while (1) 
                {
                    int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);

                    // Error occurred during receiving
                    if (len < 0) 
                    {
                        ESP_LOGE(TAG, "recv failed: errno %d", errno);
                        break;
                    }

                    // Connection closed
                    else if (len == 0) 
                    {
                        ESP_LOGI(TAG, "Connection closed");
                        break;
                    }

                    // Data received
                    else 
                    {
                        // Get the sender's IP address as string
                        if (source_addr.sin6_family == PF_INET) 
                        {
                            inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
                        } 
                        else if (source_addr.sin6_family == PF_INET6) 
                        {
                            inet6_ntoa_r(source_addr.sin6_addr, addr_str, sizeof(addr_str) - 1);
                        }

                        rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
                        ESP_LOGI(TAG, "Received %d bytes from %s:", len, addr_str);
                        ESP_LOGI(TAG, "%s", rx_buffer);

                        wifi_disconnect();
                        join_other_wifi();
                        open_udp_socket();
                        output = generate_output();         
                        close_udp_socket();
                        wifi_disconnect();
                        join_old_wifi_again();          

                        int err = send(sock, output, sizeof(output), 0);
                        if (err < 0) 
                        {
                            ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
                            break;
                        }
                    }
                }

                if (sock != -1) 
                {
                    ESP_LOGE(TAG, "Shutting down socket and restarting...");
                    shutdown(sock, 0);
                    close(sock);
                }
            }
            vTaskDelete(NULL);                  
        }       
    }
}

Проблема, с которой я сталкиваюсь, заключается в том, что TCP-соединение, по-видимому, перестало работать, когда я ' Я готов отправить ответ, как только я получу ConnectionResetError: [WinError 10054] на своем ноутбуке и Error occured during sending: errno 113 на доске, как только я попытаюсь. Есть идеи, как это исправить? Скрипт python на моем ноутбуке просто ожидает ответа в том же сокете, с которым он отправил первый пакет, в течение довольно длительного времени ожидания. Итак, Идк, плата закрыла соединение? Как я могу заново открыть соединение с моей платой, не меняя сценарий python, когда моя плата не может сама установить соединения sh и ждет, пока другие подключатся к нему?

Или я могу установить соединение с IP и портом? Я уже пытался открыть сокет клиента TCP на том же IP / порту для отправки на него и просто надеюсь, что клиент TCP на ноутбуке интерпретирует это как ответ от TCP-сервера на плате, однако он не смог подключиться.

...