2012-12-11 38 views
10

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

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を使用すると問題があるようです。これを行うには他の方法がありますか?

+4

あなたはすべてのエラーを取得するのですか?ランタイムエラーがあるかどうかを確認するために 'try-catch'を削除しようとしましたか? 'receive'にブレークポイントを設定して、それがまったく呼び出されるかどうかを確認しましたか? –

+0

'try-catch'は、複数のユーザーからの受信専用です。デバッグコードでは、例外がコンソールに出力されます。 私は他のシステムでreceiveメソッドをデバッグしようとします(これは試してみたものではありませんでした)。 –

+0

受信コードはFedoraで決して発せられません。これは、データグラムがどこから発生したかに関係なく(ローカルマシンから、Windowsボックスから送信しようとした)関係しているようです。 –

答えて

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

} 
関連する問題