C#在同一台计算机上的多个程序中接收多播UDP?

时间:2020-05-07 15:12:59

标签: c# udp udpclient

在此先感谢您的帮助。

有一个不是我编写的程序,可以在本地LAN上发送UDP组播信息包。我查看了源,看来它们已正确设置为多播。该程序是WSJT-X,如果您是Ham的操作员,可能会听说过。

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 :(得分:0)

除了在VB.net中,我做的事情差不多。

WSJT-x在我的“ HamPC”上运行,并将udp数据包发送到我的“ Programming” PC进行解码。 程序将略过呼号,并通过QRZ的XML服务查找“国家/地区”电台,并在我正在收听的乐队中出现新的国家或地区时播放声音。

我还没有在“ ProgrammingPC”上运行我的程序的2个实例,但是如果遇到了你拥有的东西,我将添加代码,以便我程序的第一个正在运行的实例将完全像接收到的那样重新广播所有数据包。我的程序要接收的第二个实例的端口。

我发现此线程正在寻找有关在WJST-x传输的UDP数据包中查找Band信息的信息。我已经很容易找到并解码了AudioFreq,TimeStamp和Signal Strength字段,现在我正在搜寻数据以查找所需的频段/频率。在我的第一代程序中很容易,该程序在15分钟后的01 16 31和41秒后每15秒重复读取all.txt文件,并确定哪些记录是新记录(通过简单的行计数)

我在Google上下搜索,但是找不到wjst-x UDP数据包的已发布结构-主要是字段的偏移量/如何对其进行解码。我通过捕获UDP数据包(逐字节查看内容)并将其与all.txt文件进行比较以查找在相同传输期间写入的记录,从而找到了上述字段。

“频段/频率”字段应该是我需要的最后一个。

我相信我的建议并将完好无损的数据包重新传输到另一个端口,以供第二个实例接收。
程序是否是第一个实例,否则都将在未安装软件的情况下启动。它在主要端口上侦听-如果在主要端口上接收的数据使用该端口进行接收,然后将接收到的数据重新广播到第二个端口。 如果在第一个端口上没有收到数据,它将切换并在第二个端口上侦听,并且不会重新广播数据。

也许可以临时解决,但应该可以。
祝你好运! -73 ne5B

相关问题