【发布时间】:2010-03-10 04:10:46
【问题描述】:
此代码在 Ubuntu、Windows 和 Mac OS X 中完美运行。它也适用于运行 Android 2.1.1 的 Nexus One。
我开始发送和侦听多播数据报,所有计算机和 Nexus One 都可以完美地看到对方。然后我在 Droid 上运行相同的代码(固件 2.0.1),每个人都会收到 Droid 发送的数据包,但 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);
}
}
这是从每个可用的有效网络接口(不是环回接口)发送多播数据报的代码。
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();
}
}
更新(2010 年 4 月 2 日) 我找到了一种让 Droid 的网络接口使用多播进行通信的方法:WifiManager.MulticastLock。
MulticastLock _wifiMulticastLock = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE)).createMulticastLock("multicastLockNameHere");
_wifiMulticastLock.acquire();
那么当你完成时......
if (_wifiMulticastLock != null && _wifiMulticastLock.isHeld())
_wifiMulticastLock.release();
完成此操作后,Droid 开始在多播组上发送和接收 UDP 数据报。
2010 年 7 月 6 日更新
根据请求,这是我当前的代码,下一个方法存在于一个抽象类中,可用于广播和多播接收器。
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() 和onDatagramReceived()
对于多播接收器,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);
}
【问题讨论】:
-
我正在尝试在我的 Nexus-One(固件 2.1.1)上接收多播数据包。我使用了上面的代码,但到目前为止还没有运气。您能否附上您的完整来源,以便我可以将其与我的进行比较?谢谢,埃亚尔
-
Eya,我添加了一个更新,希望对您有所帮助。
标签: java android multicast datagram