UDP в С# работает на Windows, но не на Linux

Я использую mono для создания программы на С#, которую нужно отправлять и получать с помощью UDP. В настоящее время моя реализация работает как ожидается в Windows, но у меня возникают проблемы с получением связи для работы с моими системами Ubuntu или Fedora.

Windows может транслировать и получать собственные дейтаграммы.
Ubuntu может транслировать и получать собственные дейтаграммы. Это широковещательные передачи принимаются Windows, но он не видит датаграммы, транслируемые Windows.
Fedora может транслировать, но не получает датаграммы из любого места (даже не самого себя). Это широковещательные передачи принимаются Windows.

Когда датаграммы не достигают ни одной из Linux-машин, функция "получать" никогда не запускается.

Это то, что у меня есть до сих пор:

int _port = 4568;
var server = new UdpClient(_port);
var send_UDP = new UdpClient();

Метод приема использует асинхронные вызовы 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 {}
}

И метод отправки;

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

После некоторого тестирования с Fedora, похоже, проблема с использованием 255.255.255.255 для трансляции. Есть ли другой способ сделать это?

Ответ 1

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

Вместо использования 255.255.255.255 для широковещания используйте свой локальный IP-адрес подсети (например, 192.168.0.255 в подсети 192.168.0.1/24). Адрес 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());
        }
    }

}