2010-03-10 31 views
5

Bu kod Ubuntu, Windows ve Mac OS X'te mükemmel çalışır. Aynı zamanda Android 2.1.1 çalıştıran bir Nexus One ile de iyi çalışır.Çok noktaya yayın Android 2.0.1 için bozuk mu (şu anda DROID'de) veya bir şey mi eksik?

Çok noktaya yayın datagramlarını gönderip dinlemeye başladım ve tüm bilgisayarlar ile Nexus One birbirlerini mükemmel şekilde görecek. Sonra ben aynı kodu bir Droid (Firmware 2.0.1) ve üzerinde çalıştırın, herkes Droid tarafından gönderilen paketleri alacak, ancak droid sadece kendi paketleri dinleyecektir.

Bu gruba gönderilen gelen paketler için çok noktaya yayın grubu üzerinde sürekli olarak dinleyen bir iş parçacığının run() yöntemidir.

Testlerimi, yönlendiricideki çok noktaya yayın desteğine sahip olduğum yerel bir ağda çalıştırıyorum. Amacım, bir multicast gruba paketler yayınlayarak cihazların birbirleriyle çevrimiçi olarak buluşmasını sağlamaktır.

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

Bu

mevcut her Geçerli bir ağ arayüzünün dışarı Noktaya Yayın Datagram gönderir kodu (yani geri besleme ara değil) 'dir. WifiManager.MulticastLock:

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

Güncelleme (2 Nisan 2010) Ben Noktaya Yayın kullanarak iletişim kurmak için Droid ağ arayüzüne sahip bir yolunu buldular. Bunu yapan sonra Sonra

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

bitirdiniz ...

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

, Droid gönderme ve bir Multicast grup UDP veri birimi almaya başladı.

Güncelleme Jul-6-2010 istek Başına

, burada sonraki yöntem hem Broadcast ve Multicast alıcıları için kullanılabilecek bir soyut sınıfın üzerinde var, benim şimdiki kod. Kişisel uzanan sınıflar onInit() ve Çoklu Yayın alıcı için

onDatagramReceived(), uygulamalıdır

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

onInit()böyle bir şey görünür: Başka bir test uyguladık

_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

Nexus-One'ımda (sabit yazılım 2.1.1) Çok Noktaya Yayın paketlerini almaya çalışıyorum. Yukarıdaki kodu kullandım, ancak şimdiye kadar hiç şansım olmadı. Lütfen tam kaynağınızı ekleyebilir miyim, böylece benimle karşılaştırılabilir miyim?Teşekkürler, Eyal – Eyal

+0

Eya, bir güncelleme ekledim, umarım yardımcı olur. – Gubatron

cevap

0

, bu kez UDP Yayını'u kullanarak. Çalışıyor.

Sonuç: Bildiğim kadarıyla firmware 2.0.1 üzerindeki Motorola Droid telefonları çok noktaya yayınları desteklemez, ancak her zaman düzenli olarak DatagramPackets'i yayın adresinde kullanabilirsiniz.

+0

Bu konudaki Güncellemeye (2 Nisan 2010) bakın. Droid'i Çok Noktaya Yayın Kilidi'ni seçerek firmware 2.0.1'i kullanarak Multicast üzerinden iletişim kurmayı başardım. "WifiManager.MulticastLock Wifi Çoklu Yayın paketleri alma izni verir. Normalde Wifi yığın paketleri açıkça bu cihaza ele alınmamıştır filtreler. Bir MulticastLock Toplamak paketleri alma yığını noktaya yayın adreslerine gönderilen neden olacaktır. Bu ekstra paketleri işleniyor Dikkat çekici bir akü boşalmasına neden olabilir ve gerekmediğinde devre dışı bırakılmalıdır. " – Gubatron