简体   繁体   中英

C# Receive Multicast UDP in multiple programs on the same machine?

Thanks in advance for any help.

There is a program, not written by me that sends UDP multicast packets of info on the local LAN. I've looked the source and it appears they are correctly setup to multicast. This program is WSJT-X which if you are a Ham operator you might have heard of.

The UDP packets contain over the air signal decodes so lots of other programs including mine are interested in these packets.

The problem I'm having is that my UDP receive seems to consume the messages so no other software running on the same machine seems to receive them once my test software starts up.

Here is simple receiver:

    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();
            }
        }
    }

This simple program receives the data sent by WSJT-X just fine.

If I clone this project to a new directory, build a new copy of the program and run it, the copy never receives any of the broadcast data while the first copy is running. Only the first running copy gets data.

If I shutdown the first copy then the second copy starts to receive the data.

This acts like the first copy is consuming the message and no other clients receive it. I'm trying to prevent that. I just want to in effect, "peek" at the messages and allow other clients to receive them.

I've tried aa bunch of different options and settings, I've looked at many examples but I have not been able to solve this issue.

Any help would be greatly appreciated.

For those of you that don't have WSJT-X, the following simple UDP sender will send UDP packets:

    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();
            }
        }
    }

I am doing much the same thing but in VB.net.

WSJT-x runs on my "HamPC" and sends the udp packets to my "Programming" PC for decode. Program skims the callsigns and looks up the stations Country/State via QRZ's XML service and plays a sound when a new state or country shows up on the band I am listening to.

I have yet to run 2 instances of my program on the "ProgrammingPC" but if I run into what you have I would add code so that the first running instance of my program will rebroadcast all of the packets exactly as received to another port for the second instance of my program to receive.

I found this thread looking for information on finding the Band information in the UDP packets transmitted by WJST-x. I've found and decoded the AudioFreq, TimeStamp and Signal Strength fields easily enough, now I'm scouring the data to locate the Band/Frequency which I need. Was easy in the first generation of my program which repeated read the all.txt file every 15 seconds at 01 16 31 and 41 seconds after the minute and determines which records are new (via simple line counting)

I have Googled high and low but cannot find a published structure of wjst-x's UDP packets - mainly offsets of the fields / how to decode them. I found the fields mentioned above by capturing the UDP packets looking at the contents byte by byte and comparing to the all.txt file for records written during the same transmissions.

The Band/Freq field should be the last one I need.

I believe my suggestion and retransmitting the packets intact to another port for the 2nd instance to receive on will work for you.
Program starts up unware if it is the 1st instance or not. It listen's on the primary port -- If data received on primary uses that port for receive and rebroadcasts the data as received to the 2nd port. If no data was received on the 1st port it would switch and to listen on the 2nd port and not rebroadcast the data.

Perhaps a bandaid of a workaround but should work.
Best of luck! - 73 ne5B

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM