Я разрабатываю базу устройств на основе модуля 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;
}