2010-03-10 14 views
5

Este código funciona perfectamente en Ubuntu, Windows y Mac OS X. También funciona bien con un Nexus One con Android 2.1.1.¿Se ha roto la multidifusión para Android 2.0.1 (actualmente en DROID) o me falta algo?

Empiezo a enviar y escuchar datagramas de multidifusión, y todas las computadoras y el Nexus One se verán perfectamente. Luego I ejecuta el mismo código en un Droid (Firmware 2.0.1), y todos obtendrán los paquetes enviados por el Droid, pero el droide solo escuchará sus propios paquetes.

Este es el método run() de un hilo que escucha constantemente en un grupo de multidifusión para los paquetes entrantes enviados a ese grupo.

Estoy ejecutando mis pruebas en una red local donde tengo habilitada la compatibilidad de multidifusión en el enrutador. Mi objetivo es que los dispositivos se conozcan a medida que se conecten transmitiendo paquetes a un grupo de multidifusión.

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

Este es el código que envía la multidifusión de Datagrama de cada interfaz de red válida disponible (que no es la interfaz de bucle).

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

actualización (abril 2 ª 2010) he encontrado una manera de tener la interfaz de red del Droid de comunicarse mediante multidifusión: WifiManager.MulticastLock.

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

Luego, cuando haya terminado ...

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

Después de hacer esto, el Droid comenzó a enviar y recibir datagramas UDP en un grupo de multidifusión.

actualización julio-6-2010

Por la petición, aquí está mi código actual, existe el siguiente método en una clase abstracta que puede ser utilizado tanto para receptores de difusión y multidifusión.

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

Sus clases se extienden deben implementar onInit() y onDatagramReceived()

Para un receptormultidifusión, onInit()se ve algo como esto:

_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

Estoy tratando de recibir paquetes de multidifusión en mi Nexus-One (firmware 2.1.1). Utilicé el código anterior, pero no tuve suerte hasta el momento. ¿Puedes adjuntar tu fuente completa para poder compararla con la mía?Gracias, Eyal – Eyal

+0

Eya, he agregado una actualización, espero que ayude. – Gubatron

Respuesta

0

he implementado otra prueba, esta vez utilizando UDP Broadcast. Funciona.

Conclusión: Según mi conocimiento, los teléfonos Motorola Droid en el firmware 2.0.1 no son compatibles con multidifusión, pero siempre puede utilizar los DatagramPackets normales en la dirección de difusión.

+0

Ver la actualización (2 de abril de 2010) en este hilo. He logrado que el Droid se comunique a través de Multicast utilizando el firmware 2.0.1 al adquirir un bloqueo de multidifusión. "WifiManager.MulticastLock Permite que una aplicación reciba paquetes de multidifusión Wifi. Normalmente, la pila de Wifi filtra paquetes no dirigidos explícitamente a este dispositivo. Al realizar una multidifusión, la pila recibirá paquetes dirigidos a direcciones de multidifusión. Procesamiento de estos paquetes adicionales puede causar un drenaje de la batería notable y se debe desactivar cuando no sea necesario ". – Gubatron

Cuestiones relacionadas