我正在开发一个聊天应用程序,其中Android客户端将使用多播(UDP)交换其IP。
每个设备都会在一个单独的线程中将其ip发送到多个客户端(运行此应用程序的所有设备)。将有另一个接收器线程将侦听这些多播数据包。这是我的代码。
//多播代码。
DatagramSocket socket = new DatagramSocket(9898);
byte buff[] = ip.getBytes();
DatagramPacket packet = new DatagramPacket(buff, buff.length, InetAddress.getByName("224.0.0.1"),9999);
socket.send(packet);
socket.close();
//接收者代码
MulticastSocket socket = new MulticastSocket(9999);
InetAddress group = InetAddress.getByName("224.0.0.1");
socket.joinGroup(group);
DatagramPacket packet;
byte[] buf = new byte[256];
byte b = 'x'; //just a separator for time being
Arrays.fill(buf,b);
packet = new DatagramPacket(buf, buf.length);
String received= "";
while(received!=null)
{
socket.receive(packet);
received = new String(packet.getData());
received = received.substring(0,received.indexOf('x'));
this.setIp(received);
System.out.println("Address: " + received);
}
socket.leaveGroup(group);
socket.close();
问题是每个设备都打印自己的地址。它似乎永远不会收听其他多播包(我的意思是它应该打印其他的ip)。我也得到一个下面的日志,不知道这是否相关。
11-04 23:56:17.985: I/OSNetworkSystem(603): mcastAddDropMembership interfaceIndex=0
任何帮助将不胜感激。
答案 0 :(得分:10)
您需要在应用中获得MulticastLock,这样您的应用才能接收未在网络上明确发送到此设备的数据包。
需要许可:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
示例代码:
// Acquire multicast lock
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
MulticastLock multicastLock = wifi.createMulticastLock("multicastLock");
multicastLock.setReferenceCounted(true);
multicastLock.acquire();
//Do some mutlicast job here
... ...
// Once your finish using it, release multicast lock
if (multicastLock != null) {
multicastLock.release();
multicastLock = null;
}
答案 1 :(得分:1)
在android中实现了IPv4多播支持。还存在杯形蛋糕时代的错误。
我遇到了类似的问题,我正在做一个依赖mDNS /多播进行服务发现的项目。我的Android应用程序根本不会订阅多播组。我通过在Ubuntu 14.04计算机上创建一个便携式访问点并在其上运行tcpdump来验证这一点。连接到它的Android设备根本不会发出加入组所需的IGMP消息。我可以发送数据包但不接收它们。
我注意到每当我加入网络时,我都会向所有系统发送IPv6加入组消息。这促使我尝试使用IPv6多播地址,但这很有效。
较新的Android设备支持IPv6,它具有内置和强制多播支持。因此,不要使用Class 4 IPv4多播地址,而是修改代码以使用IPv6地址。这将使您的代码至少在本地级别上运行。
http://developer.android.com/reference/java/net/Inet6Address.html
此页面提供了大量有关根据您的需求使用哪种IP的信息。
有人说它在没有WiFiManager.crrateMulticastLock()的情况下工作,但我没有尝试过。
理论上,向全球网络多播当然是可能的。但我从来没有见过一个成功的实际实施。鉴于周围存在深奥的路由器和防火墙。
这个问题显示了它是如何在桌面上完成的。类似的代码也适用于android。