C#中的UDP适用于Windows但不适用于Linux

Mic*_*ill 10 c# windows ubuntu mono fedora

我正在使用mono来构建一个需要使用UDP发送和接收的C#程序.目前我的实现在Windows上按预期工作,但我有问题与我的Ubuntu或Fedora系统进行通信.

Windows可以广播和接收它自己的数据报.
Ubuntu可以广播和接收它自己的数据报.它的广播是由Windows接收的,但它没有看到Windows播放的数据报.
Fedora可以广播,但不会从任何地方(甚至不是自己)接收数据报.它的广播是由Windows接收的.

当数据报无法到达任何一台Linux机器时,"接收"功能永远不会被触发.

这是我到目前为止:

int _port = 4568;
var server = new UdpClient(_port);
var send_UDP = new UdpClient();
Run Code Online (Sandbox Code Playgroud)

receive方法使用UDPClient的异步调用;

private static void receive()
{
    server.BeginReceive(new AsyncCallback(receive), null);
}
private static void receive(IAsyncResult o)
{           
    try
    {
        // I'm told that port = 0 should receive from any port.
        var sender = new IPEndPoint(IPAddress.Any, 0);
        var data = server.EndReceive(o, ref sender);
        receive();
        var str = new string(Encoding.ASCII.GetChars(data));
        postmessage(sender.Address.ToString() + ":" + sender.Port.ToString() + " > " + str);
    }
    catch {}
}
Run Code Online (Sandbox Code Playgroud)

和发送方法;

public static void send(string message)
{
    var target = new IPEndPoint(IPAddress.Parse("255.255.255.255"), _port);
    byte[] data = Encoding.ASCII.GetBytes(message);
    send_UDP.Send(data, data.Length, target);
}
Run Code Online (Sandbox Code Playgroud)

在使用Fedora进行一些测试之后,使用255.255.255.255进行广播似乎是一个问题.还有其他方法可以做到这一点吗?

Ant*_*ill 2

我已经在评论中指定了这一点,但将其作为答案,因为您可能忽略了它并且似乎没有答案。

不要使用255.255.255.255本地 IP 子网的广播地址(例如 192.168.0.1/24 子网上的 192.168.0.255)来进行广播。该255.255.255.255地址不会由路由器转发(如果您的客户端站点有多个子网,则这是相关的),而可以转发定向广播(如果如此配置)。过去的情况是,路由器默认会转发定向广播,但这在RFC2644中发生了变化,所以不要把赌注押在它上面;)。

以下是计算每个适配器的定向 IPV4 广播地址的示例:

public static void DisplayDirectedBroadcastAddresses()
{

    foreach (var iface in NetworkInterface.GetAllNetworkInterfaces()
             .Where(c => c.NetworkInterfaceType != NetworkInterfaceType.Loopback))
    {
        Console.WriteLine(iface.Description);
        foreach (var ucastInfo in iface.GetIPProperties().UnicastAddresses
                 .Where(c => !c.Address.IsIPv6LinkLocal))
        {
            Console.WriteLine("\tIP       : {0}", ucastInfo.Address);
            Console.WriteLine("\tSubnet   : {0}", ucastInfo.IPv4Mask);
            byte[] ipAdressBytes = ucastInfo.Address.GetAddressBytes();
            byte[] subnetMaskBytes = ucastInfo.IPv4Mask.GetAddressBytes();

            if (ipAdressBytes.Length != subnetMaskBytes.Length) continue;
                
            var broadcast = new byte[ipAdressBytes.Length];
            for (int i = 0; i < broadcast.Length; i++)
            {
                broadcast[i] = (byte)(ipAdressBytes[i] | ~(subnetMaskBytes[i]));
            }
            Console.WriteLine("\tBroadcast: {0}", new IPAddress(broadcast).ToString());
        }
    }
            
}
Run Code Online (Sandbox Code Playgroud)