2012-11-04 14 views
8

Zajmuję się tworzeniem aplikacji do czatu, w której klienci Android będą wymieniać swoje IP za pomocą multiemisji (UDP).Urządzenie z Androidem nie otrzymuje pakietu multicastowego

Każde urządzenie wyśle ​​swoje IP do wielu klientów (wszystkie urządzenia uruchamiające tę aplikację) w osobnym wątku. Pojawi się kolejny wątek odbiornika, który będzie nasłuchiwał tych pakietów multiemisji. Oto mój kod.

// Kod multiemisji.

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

// Odbiornik kod

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

Problemem jest każde urządzenie drukuje swój własny adres. Wydaje się, że nigdy nie słucha innych pakietów multicastowych (mam na myśli to, że powinien również drukować inne ip). Dostaję również dziennik poniżej, nie wiem, czy to jest powiązane.

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

Każda pomoc zostanie doceniona.

Odpowiedz

9

Potrzebujesz aplikacji MulticastLock, która pozwoli Twojej aplikacji odbierać pakiety, które nie są jawnie zaadresowane do tego urządzenia w sieci. wymagane

Permission: kod

<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"/> 

próbki:

// 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

Wygląda na to tylko dla pakietów multicast wifi. Korzystam z multiemisji przez Internet (przy użyciu zwykłego APN, bez WIFI). Czy nadal będzie działać? –

+0

Nie sądzę, że jest to możliwe na Androidzie, zobacz, czy odpowiedź [tutaj] (http://stackoverflow.com/questions/3068497/udp-multicast-over-the-internet) pomaga. – yorkw

+0

Dzięki, że popatrzę. –

1

multicast IPv4 wsparcie w Android jest poorely realizowane. Są jeszcze błędy z ery ciastek.

Wystąpił podobny problem, robiłem projekt, który polegał na mDNS/multicast do wykrywania usług. Moja aplikacja na Androida po prostu nie subskrybuje grupy multiemisji. Zweryfikowałem to, tworząc przenośny punkt dostępu na komputerze z Ubuntu 14.04 i uruchamiając na nim tcpdump. Podłączone do niego urządzenia z systemem Android po prostu nie emitowały komunikatów IGMP wymaganych do dołączenia do grupy. Mogłem wysyłać pakiety, ale ich nie otrzymałem.

Co zauważyłem, że otrzymywałem wiadomość grupy dołączania IPv6 do wszystkich systemów, gdy tylko dołączyłem do sieci. To skłoniło mnie do wypróbowania adresu multiemisji IPv6 i działało.

Nowsze urządzenia z Androidem obsługują protokół IPv6, który ma wbudowaną i obowiązkową obsługę multiemisji. Zamiast więc używać adresu multiemisji IPv4 klasy 4, zmodyfikuj kod, aby używał adresu IPv6. Spowoduje to, że twój kod będzie działał przynajmniej na poziomie lokalnym.

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

Ta strona zawiera wiele informacji, o których IP do wykorzystania jak na swoje potrzeby.

Niektórzy mówią, że działa bez WiFiManager.crrateMulticastLock(), ale nie próbowałem tego.

Multicasting w sieciach globalnych jest oczywiście możliwy teoretycznie. Ale nigdy nie widziałem udanej praktycznej implementacji jednej. Biorąc pod uwagę ezoteryczne routery i firewalle, które istnieją wszędzie.

To pytanie SO pokazuje, jak to zrobić na komputerze. Podobny kod działa również z Androidem.

IPv6 Multicast example

Powiązane problemy