2010-03-10 16 views
5

Dieser Code funktioniert perfekt in Ubuntu, Windows und Mac OS X. Er funktioniert auch gut mit einem Nexus One unter Android 2.1.1.Ist Multicast für Android 2.0.1 defekt (derzeit auf dem DROID) oder fehle ich etwas?

Ich fange an, Multicast-Datagramme zu senden und zu hören, und alle Computer und das Nexus One werden sich perfekt sehen. Dann ich laufen den gleichen Code auf einem Droid (Firmware 2.0.1), und jeder wird die Pakete von dem Droiden gesendet bekommen, aber der Droide wird nur auf seine eigenen Pakete hören.

Dies ist die run()-Methode eines Threads, der ständig auf einer Multicast-Gruppe auf eingehende Pakete wartet, die an diese Gruppe gesendet werden.

Ich führe meine Tests in einem lokalen Netzwerk durch, in dem ich die Multicast-Unterstützung im Router aktiviert habe. Mein Ziel ist es, dass Geräte sich gegenseitig treffen, wenn sie online gehen, indem sie Pakete an eine Multicast-Gruppe senden.

public void run() { 
    byte[] buffer = new byte[65535]; 
    DatagramPacket dp = new DatagramPacket(buffer, buffer.length); 

    try { 
     MulticastSocket ms = new MulticastSocket(_port); 
     ms.setNetworkInterface(_ni); //non loopback network interface passed 
     ms.joinGroup(_ia); //the multicast address, currently 224.0.1.16 
     Log.v(TAG,"Joined Group " + _ia); 

     while (true) { 
      ms.receive(dp); 
      String s = new String(dp.getData(),0,dp.getLength()); 
      Log.v(TAG,"Received Package on "+ _ni.getName() +": " + s); 
      Message m = new Message(); 
      Bundle b = new Bundle(); 
      b.putString("event", "Listener ("+_ni.getName()+"): \"" + s + "\""); 
      m.setData(b); 
      dispatchMessage(m); //send to ui thread 
     } 
    } catch (SocketException se) { 
     System.err.println(se); 
    } catch (IOException ie) { 
     System.err.println(ie); 
    } 
} 

Dies ist der Code, der aus jeder gültigen Netzwerk-Schnittstelle zur Verfügung (das ist nicht die Loopback-Schnittstelle), um das Multicast-Datagramm sendet.

public void sendPing() { 
    MulticastSocket ms = null; 
    try { 
     ms = new MulticastSocket(_port); 
     ms.setTimeToLive(TTL_GLOBAL); 

     List<NetworkInterface> interfaces = getMulticastNonLoopbackNetworkInterfaces(); 
     for (NetworkInterface iface : interfaces) { 
      //skip loopback 
      if (iface.getName().equals("lo")) 
       continue; 
      ms.setNetworkInterface(iface); 
      _buffer = ("FW-"+ _name +" PING ("+iface.getName()+":"+iface.getInetAddresses().nextElement()+")").getBytes(); 
      DatagramPacket dp = new DatagramPacket(_buffer, _buffer.length,_ia,_port); 
      ms.send(dp); 
      Log.v(TAG,"Announcer: Sent packet - " + new String(_buffer) + " from " + iface.getDisplayName()); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } catch (Exception e2) { 
     e2.printStackTrace(); 
    } 
} 

Update (2. April 2010) fand ich einen Weg, um den Netzwerk-Schnittstelle des Droid hat zu kommunizieren Multicast verwenden: WifiManager.MulticastLock.

MulticastLock _wifiMulticastLock = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE)).createMulticastLock("multicastLockNameHere"); 
_wifiMulticastLock.acquire(); 

Dann, wenn Sie fertig sind ...

if (_wifiMulticastLock != null && _wifiMulticastLock.isHeld()) 
    _wifiMulticastLock.release(); 

Nachdem ich das tat, begann das Droid Senden und Empfangen von UDP-Datagramme auf einer Multicast-Gruppe.

aktualisieren Juli-6-2010

pro Anfrage, hier ist meine aktuellen Code, der nächste Methode auf einer abstrakten Klasse vorhanden ist, die für beide Broadcast- und Multicast-Empfänger verwendet werden kann.

public void run() { 
    onInit(); 
    try { 
     byte[] data = new byte[65535]; 
     while (isProcessing()) { 
      try { 
       DatagramPacket receivedDatagram = new DatagramPacket(data, data.length); 
       _socket.receive(receivedDatagram); 
       onDatagramReceived(receivedDatagram); 
       data = new byte[65535]; // This pattern is for saving memory allocation. 
      } catch (InterruptedIOException e) { 
       if (!isProcessing()) 
        break; 
      } 
     } // while 

    } catch (Exception e) { 
     Log.e(TAG, e.getMessage(), e); 
    } finally { 
     onStop(); 
     _socket.close(); 
     _socket.disconnect(); 
    } 
} 

Ihre Verlängerung Klassen onInit() und onDatagramReceived()

Für einen, Multicast Empfänger implementieren sollten onInit()sieht etwas wie folgt aus:

_socket = new MulticastSocket(PORT_MULTICAST); 
InetAddress groupAddress = InetAddress.getByAddress(MULTICAST_GROUP_ADDRESS); 
InetAddress groupInetAddress = FrostWireUtils.fastResolveAddress(groupAddress); //reflection hack to not resolve ips 
try { 
    _socket.setSoTimeout(500); 
    _socket.setTimeToLive(MULTICAST_TTL_GLOBAL); 
    _socket.setReuseAddress(true); 
    _socket.setNetworkInterface(
     WifiUtils.getWifiNetworkInterface()); 
    _socket.joinGroup(groupInetAddress); 
    WifiUtils.lockMulticast(); 
} catch (Exception e) { 
    Log.e(TAG, e.getMessage(), e); 
} 
+0

Ich versuche Multicast-Pakete auf meinem Nexus-One (Firmware 2.1.1) zu erhalten. Ich habe den obigen Code verwendet, hatte aber bisher kein Glück. Können Sie bitte Ihre komplette Quelle anhängen, damit ich sie mit meiner vergleichen kann?Danke, Eyal – Eyal

+0

Eya, ich habe ein Update hinzugefügt, hoffe es hilft. – Gubatron

Antwort

0

ich einen weiteren Test, diesmal implementiert haben mit UDP Broadcast. Es funktioniert.

Fazit: Soweit ich weiß Motorola Droid Telefone auf Firmware 2.0.1 nicht Multicast unterstützen, aber Sie können immer reguläre DatagramPackets auf die Broadcast-Adresse verwenden.

+0

Siehe das Update (2. April 2010) zu diesem Thema. Ich habe es geschafft, den Droid über Multicast mit Firmware 2.0.1 kommunizieren zu lassen, indem eine Multicast-Sperre angefordert wird. "WifiManager.MulticastLock Ermöglicht einer Anwendung, Wifi-Multicast-Pakete zu empfangen. Normalerweise filtert der Wifi-Stack Pakete heraus, die nicht explizit an dieses Gerät adressiert sind. Das Empfangen einer MulticastLock bewirkt, dass der Stapel Pakete an Multicast-Adressen empfängt. Verarbeitung dieser zusätzlichen Pakete kann einen merklichen Batterieverbrauch verursachen und sollte deaktiviert werden, wenn sie nicht benötigt wird. " – Gubatron

Verwandte Themen