Большая задержка до получения данных в UDP-сокете после подключения сетевого кабеля - PullRequest
1 голос
/ 20 января 2020

Краткое описание настройки: хост A подключен напрямую к хосту B; оба имеют фиксированные IPv4-адреса в одном и том же su bnet.

Хост A (Windows 10) отправляет 400-байтовый UDP-пакет (содержащий полезные данные с возрастающими целыми числами) каждые 10 мс на фиксированный IP-адрес хост B в порту 5001 На хосте B (Windows 7) запускается простая тестовая программа. NET, которая открывает сокет UDP, привязывается к 0.0.0.0 на порту 5001 и ожидает входящих пакетов UDP.

При запуске тестовой программы на хост B сокет создается следующим образом:

byte[] rcvBuffer = new byte[16 * 1024];
Socket udpSock;

private void Start()
{
   try
   {
      udpSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
      udpSock.Bind(new IPEndPoint(IPAddress.Any, 5001));
      udpSock.BeginReceive(rcvBuffer, 0, rcvBuffer.Length, SocketFlags.None, new AsyncCallback(OnReceiveUdp), udpSock);
   }
   catch (Exception ex)
   {
      MessageBox.Show(ex.Message);

      if(udpSock != null)
      {
         try
         {
            udpSock.Close();
            udpSock = null;
         }
         catch { }
      }
   }
}

Обратный вызов приема выглядит следующим образом

private void OnReceiveUdp(IAsyncResult ar)
{
   Socket sock = ar.AsyncState as Socket;
   if (sock == null)
   {
      MessageBox.Show("Socket is null");
      return;
   }

   try
   {
      int nBytes = sock.EndReceive(ar);
      if (nBytes == 0)
      {
         MessageBox.Show("0 bytes received");
         return;
      }

      sock.BeginReceive(rcvBuffer, 0, rcvBuffer.Length, SocketFlags.None, new AsyncCallback(OnReceiveUdp), sock);
   }
   catch (Exception ex)
   {
      MessageBox.Show(ex.Message);
   }
}

Обычно все работает нормально: пакеты не отбрасываются, и мы не видим существенных задержек.

Что мы заметили, так это то, что если мы отсоединим кабель от NI C на хосте B, оставим его отсоединенным на несколько секунд, а затем снова вставим его (хост A продолжает посылать все время), запускаются UDP-пакеты появляется снова в Wireshark относительно быстро, но иногда требуется 10 секунд или больше, пока сокет UDP на хосте B не начнет получать данные снова. Первые данные, которые он получает, также не являются первым UDP-пакетом, перехваченным Wireshark, но кажется, что многие пакеты отбрасываются, прежде чем они внезапно снова передаются на транспортный уровень. После этого все снова работает нормально.

Кто-нибудь еще наблюдал это явление или знает, что может быть причиной этой относительно большой задержки?

Некоторые дополнительные примечания:

  • задержка не фиксирована; иногда даже нет никакой задержки. В других случаях это занимает 10 секунд или более
  • Проблема также по-прежнему возникает при отключении всех драйверов протокола / фильтра (кроме IPv4) для сетевого адаптера
  • Сначала мы наблюдали это поведение в режиме ядра Драйвер, который мы разрабатываем, где мы используем Windows Ядра ядра

Я знаю, что UDP подразумевает возможную потерю пакетов, но мне просто странно, что пакеты поступают в сетевую карту, но не находят пути вверх сетевой стек ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...