10

私はmonoを使用して、UDPを使用して送受信する必要があるC#プログラムを構築しています。現在、私の実装はWindowsで期待どおりに機能しますが、UbuntuまたはFedoraシステムと通信を機能させるのに問題があります。

Windowsは、独自のデータグラムをブロードキャストおよび受信できます。
Ubuntuは、独自のデータグラムをブロードキャストおよび受信できます。ブロードキャストはWindowsによって受信されますが、Windowsによってブロードキャストされたデータグラムは表示されません。
Fedoraはブロードキャストできますが、どこからでも(それ自体でさえも)データグラムを受信しません。ブロードキャストはWindowsによって受信されます。

データグラムがいずれかのLinuxマシンに到達できない場合、「receive」関数が実行されることはありません。

これは私がこれまでに持っているものです:

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

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 {}
}

そして、sendメソッド。

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を使用してブロードキャストすることに問題があるようです。これを行う他の方法はありますか?

4

1 に答える 1

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());
        }
    }
            
}
于 2013-02-13T15:34:50.313 に答える