2012-12-11 138 views
10

我使用mono来构建需要使用UDP进行发送和接收的C#程序。目前我的实现在Windows上按预期工作,但是我的通信与我的Ubuntu或Fedora系统一起工作时遇到问题。C#中的UDP在Windows上工作,但不在Linux上工作

Windows可以广播和接收它自己的数据报。
Ubuntu可以广播和接收它自己的数据报。它的广播被Windows收到,但是它没有看到由Windows广播的数据报。
Fedora可以广播,但不接收来自任何地方(甚至本身)的数据报。它的广播是由Windows收到的。

当数据报无法到达任何一台linux机器时,'receive'函数永远不会被触发。

这是我到目前为止有:

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'仅用于从多个用户接收 - 在我的调试代码中,异常被打印到控制台。 我会尝试调试其他系统上的接收方法(这不是我曾经想过的尝试)。 –

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

} 
相关问题