【问题标题】:UdpClient Receives Data on multiple listenersUdpClient 在多个侦听器上接收数据
【发布时间】:2017-11-02 19:19:40
【问题描述】:

我有一个实现自动发现机制的应用程序,但我遇到了 UdpClient 问题。只要应用程序的单个实例打开,它就可以正常工作。但是,当第二个实例打开时,只有第一个实例会接收单播数据包。有趣的是,实现相同机制的类似应用程序似乎没有这个问题。有什么建议吗?

class AutoDiscovery
{
    private UdpClient Udp;
    private IPEndPoint BroadcastEP = new IPEndPoint(IPAddress.Broadcast, 1234);
    private List<byte> AutoDiscoverPacket = new List<byte>();
    public ObservableCollection<DiscoveredDevice> DiscoveredDevices = new ObservableCollection<DiscoveredDevice>();

    public AutoDiscovery()
    {
        Udp = new UdpClient();
        Udp.ExclusiveAddressUse = false;
        Udp.EnableBroadcast = true;
        Udp.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        Udp.Client.Bind(new IPEndPoint(IPAddress.Any, 1234));

        AutoDiscoverPacket.AddRange(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
        AutoDiscoverPacket.AddRange(Encoding.ASCII.GetBytes("SomeStaticString"));
        while (AutoDiscoverPacket.Count < 123)
        {
            AutoDiscoverPacket.Add(0x00);
        }

        ReceiveDataAsync(ReceiveDataCallback);
    }

    ~AutoDiscovery()
    {
        if (Udp != null)
        {
            try
            {
                Udp.Close();
            }
            finally
            {

            }
        }
    }

    public void Discover()
    {
        DiscoveredDevices.Clear();
        Udp.Send(AutoDiscoverPacket.ToArray(), AutoDiscoverPacket.Count, BroadcastEP);
    }

    private void ReceiveDataAsync(Action<UdpReceiveResult> Callback)
    {
        Task.Run(async () =>
        {
            try
            {
                while (true)
                {
                    //IPEndPoint object will allow us to read datagrams sent from any source.
                    UdpReceiveResult receivedResults = await Udp.ReceiveAsync();
                    Callback(receivedResults);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        });
    }

    private void ReceiveDataCallback(UdpReceiveResult Result)
    {

        // Do stuff here
    }
}

}

【问题讨论】:

  • 我想记住只有一个应用程序可以一次将自己绑定到特定的 ip/port,如果有办法解决这个问题,也许你可以尝试朝这个方向搜索。

标签: c# .net udpclient


【解决方案1】:

将多个套接字绑定到相同的 IP 地址和端口组合是没有用的,默认情况下甚至是不可能的。只有设置了SO_REUSEADDR 选项(托管代码中的SocketOptionName.ReuseAddress),套接字才能共享同一IP 地址上的端口,即使这样,行为也是不确定的(通常,一个或另一个套接字将接收数据报,但不是两者都有)。

如果您可以将套接字配置为使用不同的 IP 地址(例如,您在同一台计算机上有多个网络适配器),那么它们可以侦听同一端口。

一种更通用的方法是使用 UDP 多播。然后每个服务器都可以加入多播组以接收发现数据报,并以他们为主要通信配置的唯一端口号进行响应。

以下是一些相关的问答:

C# UDP server multiple instances ipv6 same port
Listening to broadcasts when server and client are on the same machine

第二个问题实际上涉及 UDP 套接字的 UWP 实现中的一个错误,但该问题包含有关使用多播来实现此目标的基本思想的一些很好的细节。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多