2012-11-04 8 views
8

Ich entwickle eine Chat-Anwendung, bei der Android-Clients ihre IPs mit Multicasting (UDP) austauschen.Android-Gerät empfängt kein Multicast-Paket

Jedes Gerät sendet seine IP an mehrere Clients (alle Geräte, auf denen diese App läuft) in einem separaten Thread. Es wird einen weiteren Empfänger-Thread geben, der diese Multicast-Pakete abhören wird. Hier ist mein Code.

// Multicasting-Code.

DatagramSocket socket = new DatagramSocket(9898); 
      byte buff[] = ip.getBytes(); 
      DatagramPacket packet = new DatagramPacket(buff, buff.length, InetAddress.getByName("224.0.0.1"),9999); 
      socket.send(packet); 
      socket.close(); 

// Receiver Code

MulticastSocket socket = new MulticastSocket(9999); 
     InetAddress group = InetAddress.getByName("224.0.0.1"); 
     socket.joinGroup(group); 

     DatagramPacket packet; 

      byte[] buf = new byte[256]; 
      byte b = 'x'; //just a separator for time being 
      Arrays.fill(buf,b); 
      packet = new DatagramPacket(buf, buf.length); 
      String received= ""; 
      while(received!=null) 
      { 
       socket.receive(packet); 
       received = new String(packet.getData()); 
       received = received.substring(0,received.indexOf('x')); 
       this.setIp(received); 
       System.out.println("Address: " + received); 
      } 

     socket.leaveGroup(group); 
     socket.close(); 

Das Problem ist, jedes Gerät seine eigene Adresse druckt. Es scheint, dass es nie auf andere Multicast-Pakete hört (ich meine, es sollte auch andere IPs drucken). Ich bekomme auch ein Protokoll unten, nicht sicher, ob das verwandt ist.

11-04 23:56:17.985: I/OSNetworkSystem(603): mcastAddDropMembership interfaceIndex=0 

Jede Hilfe wird geschätzt.

Antwort

9

Sie müssen in Ihrer App eine MulticastLock erwerben, mit der Ihre App Pakete empfangen kann, die nicht explizit an dieses Gerät im Netzwerk adressiert sind.

Genehmigung erforderlich:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> 
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 

Beispielcode:

// Acquire multicast lock 
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE); 
MulticastLock multicastLock = wifi.createMulticastLock("multicastLock"); 
multicastLock.setReferenceCounted(true); 
multicastLock.acquire(); 

//Do some mutlicast job here 
... ... 

// Once your finish using it, release multicast lock 
if (multicastLock != null) { 
    multicastLock.release(); 
    multicastLock = null; 
} 
+0

es so aussieht, ist nur für WiFi-Multicast-Pakete. Ich bin Multicasting über das Internet (mit normalen APN, kein WIFI). Wird es noch funktionieren? –

+0

Ich glaube nicht, dass es auf Android möglich ist, ob Antwort [hier] (http://stackoverflow.com/questions/3068497/udp-multicast-over-the-internet) hilft. – yorkw

+0

Danke, ich werde es mir ansehen. –

1

IPv4-Multicast-Unterstützung in Android ist poorely implementiert. Es gibt Bugs aus Cupcake-Ära noch vorhanden.

Ich stieß auf ein ähnliches Problem Ich war ein Projekt, das auf mDNS/Multicast für Service Discovery verließ. Meine Android-App würde die Multicast-Gruppe einfach nicht abonnieren. Ich habe dies verifiziert, indem ich einen portablen Access Point auf einem Ubuntu 14.04 Rechner erstellt und tcpdump darauf ausgeführt habe. Android-Geräte, die damit verbunden waren, gaben einfach keine IGMP-Nachrichten aus, die für den Beitritt zu einer Gruppe erforderlich waren. Ich könnte Pakete senden, aber nicht empfangen.

Was mir aufgefallen ist, dass ich eine IPv6-Join-Gruppen-Nachricht an alle Systeme bekam, wann immer ich mich dem Netzwerk anschloss. Dies veranlasste mich, eine IPv6-Multicast-Adresse auszuprobieren, und das hat funktioniert.

Neuere Android-Geräte unterstützen IPv6 mit integrierter und obligatorischer Multicast-Unterstützung. Anstatt eine IPv4-Multicastadresse der Klasse 4 zu verwenden, ändern Sie den Code so, dass eine IPv6-Adresse verwendet wird. Dadurch wird Ihr Code mindestens auf lokaler Ebene funktionieren.

http://developer.android.com/reference/java/net/Inet6Address.html

Diese Seite hat eine Fülle von Informationen darüber, welche IP nach Ihren Bedürfnissen zu nutzen.

Einige sagen, dass es ohne den WiFiManager.crrateMulticastLock() funktioniert, aber ich habe das nicht versucht.

Multicasting zu globalen Netzwerken ist theoretisch möglich. Aber ich habe nie eine erfolgreiche praktische Umsetzung von einem gesehen. Angesichts der esoterischen Router und Firewalls, die überall vorhanden sind.

Diese SO Frage zeigt, wie es auf dem Desktop gemacht wird. Ein ähnlicher Code funktioniert auch mit Android.

IPv6 Multicast example

Verwandte Themen