2010-03-10 5 views
5

이 코드는 Ubuntu, Windows 및 Mac OS X에서 완벽하게 작동합니다. Android 2.1.1을 실행하는 Nexus One에서도 잘 작동합니다.Android 2.0.1 (현재 DROID에 있음)에서 멀티 캐스트가 작동하지 않습니까?

멀티 캐스트 데이터 그램의 송수신이 시작되고 모든 컴퓨터와 Nexus One이 서로를 완벽하게 볼 수 있습니다. 그런 다음 Droid (펌웨어 2.0.1)에서 동일한 코드를 실행하면 모두 Droid에서 보낸 패킷을 받게되지만 드로이드는 자체 패킷 만 수신합니다.

이것은 수신 대기중인 패킷에 대해 멀티 캐스트 그룹에서 끊임없이 수신 대기하는 스레드의 방법입니다 (run()).

라우터에서 멀티 캐스트 지원을 사용할 수있는 로컬 네트워크에서 테스트를 실행하고 있습니다. 내 목표는 멀티 캐스트 그룹에 패키지를 브로드 캐스트하여 온라인 상태가되면 장치가 서로 만날 수 있도록하는 것입니다.

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

이 코드는 루프백 인터페이스가 아닌 모든 유효한 네트워크 인터페이스에서 멀티 캐스트 데이터 그램을 보내는 코드입니다. 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(); 
    } 
} 

업데이트 (4 월 2 일 2010) 나는 멀티 캐스트 사용하여 통신 할 수있는 드로이드의 네트워크 인터페이스를 가질 수있는 방법을 발견했다. 내가 이런 짓을 한 후 다음

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

이 완료 ...

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

는 드로이드 전송 및 멀티 캐스트 그룹에 UDP 데이터 그램을 받기 시작했다.

업데이트 7 월 6-2010의 요청에 따라

, 여기에 다음 방법은 모두 브로드 캐스트 및 멀티 캐스트 수신기에 사용할 수있는 추상 클래스에 존재하는, 내 현재 코드입니다. 귀하의 확장 클래스 onInit()멀티 캐스트 수신기

onDatagramReceived()을 구현해야

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()는 다음과 같이 보이는 : 나는 다른 테스트를 구현했습니다

_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 (펌웨어 2.1.1)에서 멀티 캐스트 패킷을 수신하려고합니다. 위의 코드를 사용했지만 지금까지 행운이 없었습니다. 완전한 소스를 첨부하여 제 광산과 비교할 수 있습니까?감사합니다. Eyal – Eyal

+0

Eya, 업데이트를 추가했습니다. 도움이되기를 바랍니다. – Gubatron

답변

0

,이 시간을 UDP 브로드 캐스트을 사용하십시오. 작동합니다.

결론 : 필자의 지식 범위 내에서 펌웨어 2.0.1의 Motorola Droid 전화는 멀티 캐스트를 지원하지 않지만 브로드 캐스트 주소에는 항상 정규적인 DatagramPackets를 사용할 수 있습니다.

+0

이 스레드의 업데이트 (2010 년 4 월 2 일)를 참조하십시오. 저는 Droid가 멀티 캐스트 락을 aqcquiring하여 펌웨어 2.0.1을 사용하여 멀티 캐스트를 통해 통신하도록했습니다. 응용 프로그램이 Wifi Multicast 패킷을 수신 할 수 있도록 허용합니다. 일반적으로 Wifi 스택은이 장치에 명시 적으로 지정되지 않은 패킷을 걸러냅니다 .MulticastLock을 획득하면 스택이 멀티 캐스트 주소로 지정된 패킷을 수신하게됩니다. 눈에 띄는 배터리가 소모 될 수 있으며 필요하지 않을 경우 비활성화해야합니다. " – Gubatron

관련 문제