2010-03-10 16 views
5

Mã này hoạt động hoàn hảo trên Ubuntu, Windows và Mac OS X. Nó cũng hoạt động tốt với Nexus One chạy Android 2.1.1.Multicast có bị hỏng cho Android 2.0.1 (hiện tại trên DROID) hay tôi đang thiếu thứ gì đó?

Tôi bắt đầu gửi và nghe các gói dữ liệu đa hướng và tất cả các máy tính và Nexus One sẽ nhìn thấy nhau một cách hoàn hảo. Sau đó, tôi chạy cùng một mã trên Droid (Firmware 2.0.1) và mọi người sẽ nhận được các gói được gửi bởi Droid, nhưng droid sẽ chỉ nghe các gói riêng của mình.

Đây là phương pháp run() của chuỗi liên tục lắng nghe trên nhóm Multicast cho các gói gửi đến được gửi đến nhóm đó.

Tôi đang chạy các thử nghiệm của mình trên mạng cục bộ nơi tôi đã bật hỗ trợ đa phương tiện trong bộ định tuyến. Mục tiêu của tôi là để các thiết bị gặp nhau khi chúng trực tuyến bằng cách phát các gói cho một nhóm phát đa hướng.

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

Đây là mã gửi Multicast Datagram ra khỏi mọi giao diện mạng hợp lệ có sẵn (không phải giao diện loopback).

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

Cập nhật (ngày 2 tháng 4 2010) Tôi tìm thấy một cách để có giao diện mạng của Droid để giao tiếp sử dụng Multicast: WifiManager.MulticastLock.

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

Sau đó, khi bạn đã hoàn tất ...

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

Sau khi tôi đã làm điều này, Droid bắt đầu gửi và nhận UDP datagrams vào một nhóm Multicast.

Cập nhật tháng bảy-6-2010

Theo yêu cầu, đây là mã hiện tại của tôi, phương pháp tiếp theo tồn tại trên một lớp trừu tượng có thể được sử dụng cho cả máy thu phát sóng và Multicast.

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

lớp mở rộng của bạn nên thực hiện onInit()onDatagramReceived()

Đối với một Multicast nhận, onInit()trông giống như thế này:

_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

Tôi đang cố gắng nhận các gói Multicast trên Nexus-One (firmware 2.1.1). Tôi đã sử dụng mã ở trên, nhưng không có may mắn cho đến nay. Bạn có thể đính kèm nguồn hoàn chỉnh của mình để tôi có thể so sánh nó với tôi không?Cảm ơn, Eyal – Eyal

+0

Eya, tôi đã thêm bản cập nhật, hy vọng nó sẽ giúp ích. – Gubatron

Trả lời

0

Tôi đã thực hiện thử nghiệm khác, lần này sử dụng UDP Phát sóng. Nó hoạt động.

Kết luận: Trong phạm vi kiến ​​thức của tôi Điện thoại Motorola Droid trên firmware 2.0.1 không hỗ trợ phát đa hướng, nhưng bạn luôn có thể sử dụng DatagramPackets thông thường trên địa chỉ quảng bá.

+0

Xem Cập nhật (ngày 2 tháng 4 năm 2010) về chủ đề này. Tôi đã quản lý để Droid truyền thông qua Multicast bằng chương trình cơ sở 2.0.1 bằng cách aqcquiring Multicast Lock. "WifiManager.MulticastLock Cho phép ứng dụng nhận gói WiMast Wifi. Thông thường, ngăn xếp Wifi lọc ra các gói không được giải quyết rõ ràng cho thiết bị này. Việc xử lý MulticastLock sẽ khiến ngăn xếp nhận các gói được gửi tới địa chỉ multicast. có thể gây hao pin đáng chú ý và nên tắt khi không cần thiết. " – Gubatron

Các vấn đề liên quan