ESP32组播UDP高丢失(接收)

时间:2018-07-03 08:32:33

标签: sockets udp wifi multicast esp32

我正在开发基于ESP32模块的设备,该设备的UDP套接字打开仅用于在一个端口上接收广播数据包(准确地说是7890)。问题在于数据丢失率很高-大约90%。我的测试设置是:

  • ESP32-通过开放的UDP接收任务连接到WiFi网络(以下代码)
  • PC通过LAN连接到同一网络,且UDP终端设置为brodacast到远程:192.168.10.255:7890
  • 已将连接到WiFi且UDP终端设置为远程广播到192.168.10.255:7890的手机

当我从PC或手机发送东西时,手机和PC之间没有数据丢失,但是ESP32接收了我从两个发送者发送的大约10%的数据。如果我在PC或Phone上从多播更改为单播以将数据发送到ESP32,它可以正常工作。

我知道UDP不能保证传送速度,但是10%的效率对我来说似乎太低了,尤其是当繁忙的网络似乎没有问题时,因为PC和移动设备一直都在接收数据。

您对代码或菜单设置中可以更改的某些设置有任何建议吗? 目前,我的应用程序只有两项任务:

  • 连接后只是等待事件的WiFi任务
  • 代码在下面的UDP任务

更新04.07.2018(13:15)

当我不初始化蓝牙时,问题消失了。抱歉,我之前没有提到初始化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 :(得分:0)

即使UDP被认为是一劳永逸的(与TCP不同),通过WiFi的单播UDP是可靠的,因为WiFi协议中内置了可靠性。但这仅对单播有效,因为有一个已知的收件人。组播UDP不可靠,因为没有检查和重试。

当我尝试在ESP8266中使用多播UDP时,我遇到了同样的问题。这使我更加深入地研究了这个问题。最后,我使用UDP多播进行发现,但随后切换到单播UDP以进行后续传输。

请参阅组播Wifi问题声明 https://tools.ietf.org/id/draft-mcbride-mboned-wifi-mcast-problem-statement-01.html