Sha*_*dne 8 java networking android
我正在开发一个聊天应用程序,其中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();
Run Code Online (Sandbox Code Playgroud)
//接收者代码
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();
Run Code Online (Sandbox Code Playgroud)
问题是每个设备都打印自己的地址.它似乎永远不会收听其他多播包(我的意思是它应该打印其他的ip).我也得到一个下面的日志,不知道这是否相关.
11-04 23:56:17.985: I/OSNetworkSystem(603): mcastAddDropMembership interfaceIndex=0
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激.
yor*_*rkw 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"/>
Run Code Online (Sandbox Code Playgroud)
示例代码:
// 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;
}
Run Code Online (Sandbox Code Playgroud)
Android 中的 IPv4 多播支持实现得很差。纸杯蛋糕时代的错误仍然存在。
我在做一个依赖 mDNS/多播进行服务发现的项目时遇到了类似的问题。我的 Android 应用程序根本不会订阅多播组。我通过在 Ubuntu 14.04 计算机上创建便携式接入点并在其上运行 tcpdump 来验证这一点。连接到它的 Android 设备根本不会发出加入组所需的 IGMP 消息。我可以发送数据包但无法接收它们。
我注意到,每当我加入网络时,我都会收到一条发送给所有系统的 IPv6 加入组消息。这促使我尝试 IPv6 多播地址并且成功了。
较新的 Android 设备支持 IPv6,它具有内置的强制多播支持。因此,不要使用 4 类 IPv4 多播地址,而是修改代码以使用 IPv6 地址。这将使您的代码至少在本地级别上工作。
http://developer.android.com/reference/java/net/Inet6Address.html
此页面提供了大量有关根据您的需要使用哪个 IP 的信息。
有人说它无需 WiFiManager.crrateMulticastLock() 即可工作,但我没有尝试。
从理论上讲,向全球网络进行多播当然是可能的。但我从未见过成功的实际实施。考虑到周围存在着深奥的路由器和防火墙。
This SO Question 显示了它是如何在桌面上完成的。类似的代码也适用于 android。