Dieser Code funktioniert perfekt in Ubuntu, Windows und Mac OS X. Er funktioniert auch gut mit einem Nexus One unter Android 2.1.1.Ist Multicast für Android 2.0.1 defekt (derzeit auf dem DROID) oder fehle ich etwas?
Ich fange an, Multicast-Datagramme zu senden und zu hören, und alle Computer und das Nexus One werden sich perfekt sehen. Dann ich laufen den gleichen Code auf einem Droid (Firmware 2.0.1), und jeder wird die Pakete von dem Droiden gesendet bekommen, aber der Droide wird nur auf seine eigenen Pakete hören.
Dies ist die run()
-Methode eines Threads, der ständig auf einer Multicast-Gruppe auf eingehende Pakete wartet, die an diese Gruppe gesendet werden.
Ich führe meine Tests in einem lokalen Netzwerk durch, in dem ich die Multicast-Unterstützung im Router aktiviert habe. Mein Ziel ist es, dass Geräte sich gegenseitig treffen, wenn sie online gehen, indem sie Pakete an eine Multicast-Gruppe senden.
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);
}
}
Dies ist der Code, der aus jeder gültigen Netzwerk-Schnittstelle zur Verfügung (das ist nicht die Loopback-Schnittstelle), um das Multicast-Datagramm sendet.
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();
}
}
Update (2. April 2010) fand ich einen Weg, um den Netzwerk-Schnittstelle des Droid hat zu kommunizieren Multicast verwenden: WifiManager.MulticastLock.
MulticastLock _wifiMulticastLock = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE)).createMulticastLock("multicastLockNameHere");
_wifiMulticastLock.acquire();
Dann, wenn Sie fertig sind ...
if (_wifiMulticastLock != null && _wifiMulticastLock.isHeld())
_wifiMulticastLock.release();
Nachdem ich das tat, begann das Droid Senden und Empfangen von UDP-Datagramme auf einer Multicast-Gruppe.
aktualisieren Juli-6-2010
pro Anfrage, hier ist meine aktuellen Code, der nächste Methode auf einer abstrakten Klasse vorhanden ist, die für beide Broadcast- und Multicast-Empfänger verwendet werden kann.
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();
}
}
Ihre Verlängerung Klassen onInit()
und onDatagramReceived()
Für einen, Multicast Empfänger implementieren sollten onInit()
sieht etwas wie folgt aus:
_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);
}
Ich versuche Multicast-Pakete auf meinem Nexus-One (Firmware 2.1.1) zu erhalten. Ich habe den obigen Code verwendet, hatte aber bisher kein Glück. Können Sie bitte Ihre komplette Quelle anhängen, damit ich sie mit meiner vergleichen kann?Danke, Eyal – Eyal
Eya, ich habe ein Update hinzugefügt, hoffe es hilft. – Gubatron