UDP — Отправка многоадресного сообщения и прослушивание ответа приводит к исключению SocketException

#c# #udp #multicast

#c# #udp #многоадресная рассылка

Вопрос:

Я отправляю многоадресное сообщение UDP, чтобы найти определенные устройства в сети. Затем я прослушиваю ответ на порту 5001.

Мой рабочий процесс выглядит следующим образом:

  1. Отправьте многоадресное сообщение «найти» в локальную подсеть.
  2. Любые устройства wiznet в сети отвечают информационным пакетом, который я хочу получить

Все это отлично работает в Windows XP, но в Windows 7 я получаю исключение типа SocketException: *

Обычно допускается только одно использование каждого адреса сокета (протокол / сетевой адрес / порт)

Я вижу, что многоадресное сообщение отправляется в Wireshark, и я вижу ответ от устройства (устройств), но мой код не отвечает. Мой код выглядит следующим образом:

   public void StartListen()
  {
      SendFind();
      try {
          IPEndPoint localEp = new IPEndPoint(IPAddress.Any, 0);
          UdpClient listenClient = new UdpClient(5001);

          UdpState s = new UdpState();
          s.endpoint = localEp;
          s.client = listenClient;

          //allow time for the find to work - aka clutching at straws
          Thread.Sleep(500);

          while (listenClient.Available > 0)
          {
              listenClient.BeginReceive(ReceiveCallback, s);
              Thread.Sleep(500);
          }
      }

      catch (SocketException e)
      {
          Trace.WriteLine("Could not bind to socket on "   _localPort);
      }

      listenClient.Close();
  }
  

.. и получению обратного вызова ..

 private void ReceiveCallback(IAsyncResult ar)
{
    UdpClient u = (UdpClient)((UdpState)(ar.AsyncState)).client;
    IPEndPoint e = (IPEndPoint)((UdpState)(ar.AsyncState)).endpoint;
    Byte[] receiveBytes = u.EndReceive(ar, ref e);
    rxByteList.Add(receiveBytes);
    messageRxed = true;
}
  

** ОБНОВИТЬ **

Итак, я пробовал различные способы структурирования этого кода. Похоже, что проблема связана с отправкой и получением на разных UdpClients. Мое исключение было вызвано созданием UdpClient для получения сразу после открытия его для отправки — добавление задержки между отправкой и получением исправило это.

Я изменил свой код, чтобы использовать один и тот же UdpClient для отправки и получения, но я все еще ничего не получаю при получении.

Комментарии:

1. Очевидно, что сокет, привязанный к порту 5001, уже существует. Это может быть уже запущенное приложение или ваш собственный код. Дважды проверьте, что вы не привязываете несколько сокетов к одному и тому же порту, и попробуйте, работает ли другой порт.

2. Возможно, я упускаю что-то очевидное, но я совершенно уверен, что проблема не в этом. У меня больше ничего не привязано к порту 5001, и код работает на xp. Также попробовал это на «чистой» машине с Windows 7 без радости

3. На самом деле, это не то место, где генерируется исключение, а скорее то, где исключение перехватывается! Исключение генерируется до этого, вероятно, вызовом UdpClient конструктора или, возможно, вызовом BeginReceive . Можете ли вы сказать нам, какое именно?

4. На каком компьютере запущена программа, отправляющая многоадресную рассылку?

5. Извините — глупая ошибка с комментарием об исключении! Оно вызывается при вызове конструктора UdpClient. Странно то, что если я выполняю программу с самого начала и вызываю конструктор «F10», исключение не генерируется… Многоадресная рассылка отправляется с моего компьютера (win 7)

Ответ №1:

Сортировано! Это произошло потому, что мой Sendpacket использовал «udpclient.connect», который ограничивает получение всеми данными в конечной точке, предоставленными методу connect.