C# Получать Multicast UDP в нескольких программах на одном компьютере? - PullRequest
0 голосов
/ 07 мая 2020

Заранее благодарим за любую помощь.

Есть программа, написанная не мной, которая отправляет многоадресные UDP-пакеты информации по локальной сети. Я просмотрел источник, и оказалось, что они правильно настроены для многоадресной рассылки. Это программа WSJT-X, о которой вы, возможно, слышали, если вы оператор любительского телевидения.

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

Проблема, с которой я столкнулся, заключается в том, что мой прием UDP, похоже, поглощает сообщения, поэтому никакое другое программное обеспечение, работающее на той же машине, похоже, не получает их после запуска моего тестового программного обеспечения.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;

    namespace ReadUDP
    {
        internal class Program
        {
            private static void Main(string[] args)
            {
                // Setup
                int port = 2237;
                var multicastIP = IPAddress.Parse("225.0.0.1");

                // Create endpoints
                var remoteEndPoint = new IPEndPoint(multicastIP, port);
                var localEndPoint = new IPEndPoint(IPAddress.Any, port);

                // Create and configure UdpClient
                var udpclient = new UdpClient();

                udpclient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                udpclient.ExclusiveAddressUse = false;

                udpclient.Client.MulticastLoopback = true;
                udpclient.MulticastLoopback = true;

                // Bind, Join
                udpclient.Client.Bind(localEndPoint);
                udpclient.JoinMulticastGroup(multicastIP, IPAddress.Any);

                Task.Run(() =>
                {
                    IPEndPoint sender = new IPEndPoint(0, 0);
                    while (true)
                    {
                        var recvBuffer = udpclient.Receive(ref sender);
                        var recvStr = Encoding.UTF8.GetString(recvBuffer);

                        Console.WriteLine("--------------------------------------------------------------------------");
                        Console.WriteLine($"From:{sender} Data:{recvStr}");
                        Console.WriteLine("--------------------------------------------------------------------------");
                    }
                });

                Console.ReadLine();
            }
        }
    }

Эта простая программа прекрасно принимает данные, отправленные WSJT-X.

Если я клонирую этот проект в новый каталог, создайте новую копию программы и запустите ее, копия никогда не получает никаких широковещательных данных, пока работает первая копия. Только первая работающая копия получает данные.

Если я отключу первую копию, тогда вторая копия начнет получать данные.

Это действует так, как будто первая копия принимает сообщение, а другие клиенты получить это. Я пытаюсь предотвратить это. Я просто хочу, по сути, «заглядывать» в сообщения и разрешать другим клиентам их получать.

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

Любая помощь будет принята с благодарностью.

Для тех из вас, у кого нет WSJT-X, следующий простой отправитель UDP будет отправлять пакеты UDP:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;

    namespace ReadUDP
    {
        internal class Program
        {
            private static void Main(string[] args)
            {
                // Setup
                int port = 2237;
                var multicastIP = IPAddress.Parse("225.0.0.1");

                // Create endpoints
                var remoteEndPoint = new IPEndPoint(multicastIP, port);
                var localEndPoint = new IPEndPoint(IPAddress.Any, port);

                // Create and configure UdpClient
                var udpclient = new UdpClient();

                udpclient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                udpclient.ExclusiveAddressUse = false;

                udpclient.Client.MulticastLoopback = true;
                udpclient.MulticastLoopback = true;

                // Bind, Join
                udpclient.Client.Bind(localEndPoint);
                udpclient.JoinMulticastGroup(multicastIP, IPAddress.Any);

                Task.Run(() =>
                {
                    int msgnum = 1;
                    while (true)
                    {
                        var msg = $"Sending message {msgnum++}";

                        Console.WriteLine("--------------------------------------------------------------------------");
                        Console.WriteLine($"Send: {msg}");
                        Console.WriteLine("--------------------------------------------------------------------------");

                        var bytes = Encoding.UTF8.GetBytes(msg);
                        udpclient.Send(bytes, bytes.Length, remoteEndPoint);

                        Task.Delay(2000).Wait();
                    }
                });

                Console.ReadLine();
            }
        }
    }

1 Ответ

0 голосов
/ 11 июня 2020

Я делаю то же самое, но в VB. net.

WSJT-x работает на моем "HamP C" и отправляет пакеты udp на мой "Programming" P C для декодирования. Программа просматривает позывные и ищет станцию ​​Country / State через службу QRZ XML и воспроизводит звук, когда новый штат или страна появляется на диапазоне, который я слушаю.

Мне еще предстоит запустить 2 экземпляра моей программы на «ProgrammingP C», но если я столкнусь с тем, что есть у вас, я бы добавил код, чтобы первый запущенный экземпляр моей программы ретранслировал все пакеты точно в том виде, в котором они были получены, на другой порт, который должен получить второй экземпляр моей программы.

Я нашел эту ветку в поисках информации о нахождении информации Band в пакетах UDP, передаваемых WJST-x. Я достаточно легко нашел и декодировал поля AudioFreq, TimeStamp и Signal Strength, теперь я просматриваю данные, чтобы найти нужный диапазон / частоту. Это было легко в первом поколении моей программы, которая повторяла чтение файла all.txt каждые 15 секунд в 01, 16, 31 и 41 секунду после минуты и определяла, какие записи являются новыми (с помощью простого подсчета строк)

У меня есть Погуглил высокий и низкий, но не смог найти опубликованную структуру UDP-пакетов wjst-x - в основном смещения полей / способы их декодирования. Я нашел упомянутые выше поля, захватив UDP-пакеты, посмотрев побайтово содержимое и сравнив с файлом all.txt записи, записанные во время тех же передач.

Поле Band / Freq должно быть последним, которое мне нужно.

Я считаю, что мое предложение и повторная передача пакетов без изменений на другой порт для второго экземпляра, который будет принимать, сработают для вас.
Программа запускается без программного обеспечения, если это 1-й экземпляр или нет. Он прослушивает основной порт - если данные, полученные на основном, используют этот порт для приема, и ретранслирует полученные данные на второй порт. Если данные не были получены на 1-й порт, он переключится и будет прослушивать 2-й порт, а не ретранслировать данные.

Возможно, это обходной путь, но он должен работать.
Удачи! - 73 не5Б

...