ESP32 Multicast UDP Высокие потери (прием) - PullRequest
0 голосов
/ 03 июля 2018

Я разрабатываю базу устройств на основе модуля ESP32, в котором сокет UDP открыт только для приема широковещательных пакетов на один порт (точнее 7890). Проблема в том, что потери данных высоки - около 90%. Моя тестовая установка:

  • ESP32 - подключен к сети WiFi с открытой задачей приема UDP (код ниже)
  • ПК, подключенный к той же сети через локальную сеть с терминалом UDP, установленным для удаленного brodacast: 192.168.10.255:7890
  • Мобильный телефон, подключенный к WiFi с помощью терминала UDP, настроенного на удаленный доступ: 192.168.10.255:7890

Когда я отправляю что-либо с ПК или мобильного телефона, между мобильным телефоном и ПК нет потери данных, но ESP32 получает около 10% данных, которые я передаю от обоих отправителей. Если я переключаюсь с многоадресной на одноадресную на ПК или телефоне для отправки данных в ESP32, это работает без проблем.

Я знаю, что UDP не гарантирует доставку, но 10% -ная эффективность кажется мне очень низкой, особенно когда кажется, что нет проблем с загруженной сетью, потому что ПК и мобильный телефон принимают данные все время.

Есть ли у вас какие-либо предложения по коду или некоторым настройкам, которые можно изменить в настройках меню? На данный момент у моего приложения есть только две задачи:

  • WiFi Задача, которая после подключения просто ждет события
  • Задача UDP, что код ниже

Обновление 04.07.2018 (13:15)

Проблема исчезает, когда я не инициализирую Bluetooth. Извините, что я не упомянул ранее об инициализации BT, но я сохранил функцию инициализации из моей обычной программы, у которой намного больше задач (включая BT), и полностью забыл об этом сам.

В любом случае - вы думаете, что есть какая-то проблема с совместным использованием ресурса, или это какое-то физическое вмешательство? Я использую ESP32-DevKitC, который находится на макете, поэтому дополнительного экранирования нет.


#define PORT_NUMBER 7890
#define BUFLEN 100

void udp_task(void *pvParameter)
{
   struct sockaddr_in clientAddress;
   struct sockaddr_in serverAddress;
   struct sockaddr_in si_other;
   unsigned int slen = sizeof(si_other);
   unsigned int recv_len;
   char buf[BUFLEN];
   int sock;

   printf("UDP Task: Opening..\n");

   int ret;
   ret = UDP_List_Open(&clientAddress, &serverAddress, &sock);

   if(ret == 0)
   {
      printf("UDP Task: Open\n");
   }
   else
   {
      printf("UDP Task: Can't open\n");
   }


    while(1)
    {
        memset(buf,0,100);

        if ((recv_len = recvfrom(sock, buf, 100, 0, (struct sockaddr *) &si_other, &slen)) == -1)
        {
            printf("UDP error\n");
            break;
        }

        sendto(sock, buf, recv_len, 0, (struct sockaddr *)&si_other, sizeof(si_other));

        printf("UDP Task: Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
        printf("UDP Task: Data: %s -- %d\n" , buf, recv_len);
    }

   while(1)
   {
      vTaskDelay(100 / portTICK_RATE_MS);
   }
}


int UDP_List_Open(struct sockaddr_in* clientAddress, struct sockaddr_in* serverAddress, int* sock)
{
    // Create a socket that we will listen upon.
   *sock = socket(AF_INET, SOCK_DGRAM, 0);
   if (*sock < 0)
   {
      printf("UDP List Open: Socket error\n");
      return 1;
   }

   // Bind our server socket to a port.
   serverAddress->sin_family = AF_INET;
   serverAddress->sin_addr.s_addr = htonl(INADDR_ANY);
   serverAddress->sin_port = htons(PORT_NUMBER);
   int rc  = bind(*sock, serverAddress, sizeof(*serverAddress));
   if (rc < 0)
   {
      printf("UDP List Open: Bind error\n");
      return 2;
   }

   return 0;
}

1 Ответ

0 голосов
/ 03 июля 2018

Несмотря на то, что UDP считается запущенным и забытым (в отличие от TCP), одноадресный UDP через WiFi является надежным, поскольку надежность встроена в протокол WiFi. Но это может работать для Unicast только потому, что есть один известный получатель. UDP многоадресной передачи ненадежен, потому что нет никаких проверок и повторных попыток.

У меня была такая же проблема, когда я пытался использовать многоадресный UDP с ESP8266. Это заставило меня углубиться в проблему. В конце я использую многоадресную передачу UDP для обнаружения, но затем переключаюсь на одноадресную передачу UDP для последующих передач.

См. Multicast Wifi: описание проблемы https://tools.ietf.org/id/draft-mcbride-mboned-wifi-mcast-problem-statement-01.html

...