Обнаружение нескольких устройств в сети с использованием UDP-трансляции - C# - PullRequest
0 голосов
/ 30 апреля 2020

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

Я разработал систему, которая находится в сети и работает на сервере UDP. Получив сообщение на некоторый порт (AP), он отправит ответ обратно отправляющему IP / порту.

На стороне C# я использую следующий код:

UdpClient Client = new UdpClient();
                var RequestData = Encoding.ASCII.GetBytes("Discover");
                var ServerEp = new IPEndPoint(IPAddress.Any, 0);
                byte[] ServerResponseData = { 0 };

                Client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 1000);

                Client.EnableBroadcast = true;
                Client.Send(RequestData, RequestData.Length, new IPEndPoint(IPAddress.Broadcast, AnnouncePort));

                ServerResponseData = LanguageUtils.IgnoreErrors(() => Client.Receive(ref ServerEp));

                if (ServerResponseData != null)
                {
                    var ServerResponse = Encoding.ASCII.GetString(ServerResponseData);

                    deviceList.Add(ServerEp.Address.ToString());

                    QueryFoundDevices(deviceList);
                    AvailableDevicesList.Nodes[0].Expand();
                }

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

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

static void OnUdpData(IAsyncResult result)
        {
            // this is what had been passed into BeginReceive as the second parameter:
            UdpClient socket = result.AsyncState as UdpClient;
            // points towards whoever had sent the message:
            IPEndPoint source = new IPEndPoint(0, 0);
            // get the actual message and fill out the source:
            byte[] message = socket.EndReceive(result, ref source);
            // do what you'd like with `message` here:
            Console.WriteLine("Got " + message.Length + " bytes from " + source);
            // schedule the next receive operation once reading is done:
            socket.BeginReceive(new AsyncCallback(OnUdpData), socket);
        }

Кто-нибудь может посоветовать, пожалуйста, как мне это сделать?

Обновление: На основе комментариев - это устройства на базе Ethe rnet и я убедился, что оба устройства отвечают с помощью Wireshark.

1 Ответ

0 голосов
/ 30 апреля 2020

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

                UdpClient Client = new UdpClient();
                var RequestData = Encoding.ASCII.GetBytes("Discover");
                var ServerEp = new IPEndPoint(IPAddress.Any, 0);
                byte[] ServerResponseData = { 0 };

                Client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 1000);

                Client.EnableBroadcast = true;
                Client.Send(RequestData, RequestData.Length, new IPEndPoint(IPAddress.Broadcast, AnnouncePort));

                ServerResponseData = LanguageUtils.IgnoreErrors(() => Client.Receive(ref ServerEp));
                string ServerResponse;
                while (ServerResponseData != null)
                {
                    ServerResponse = Encoding.ASCII.GetString(ServerResponseData);

                    deviceList.Add(ServerEp.Address.ToString());

                    QueryFoundDevices(deviceList);
                    AvailableDevicesList.Nodes[0].Expand();

                    ServerResponseData = LanguageUtils.IgnoreErrors(() =>Client.Receive(ref ServerEp))
                }

Лекс Ли указал, что первый фрагмент кода, который я разместил в своем ответе, получит только первый ответ. Я попытался прочитать следующий ответ, и это сработало. Сейчас я использую вышеупомянутое, которое, вероятно, нуждается в дальнейшей оптимизации, но пока работает хорошо.

Спасибо за помощь, ребята!

...