Android 如何接收组播

在项目中用的使用组播的方式接受udp数据,顺便就记录一下相关姿势。

什么是组播(Multicast)

在发送方和每一个接受方之间实现点对多点的网络传输。组播是Ip网络数据传输方式三种之一,其他两种是广播和单播。加入组播组之后可以接受到该组播中发送的消息,包括可以接受自己发出的组播。组播的IP地址范围为224.0.0.0到239.255.255.255,有些同学接受不到组播有可能就是这个IP地址写错了。

组播如何使用

组播在基本的udp传输实现上只要添加加入组播的api就可以了,比如之前项目udp使用 :

DatagramSocket  socket = new DatagramSocket();

生成socket之后如果想发送udp包,使用:

DatagramPacket sendPacket 
            = new DatagramPacket(sendBuf ,sendBuf.length , addr , port);

其中sendBuf是要发送的字节数组,sendBuf.length是要发送内容的长度,adds是服务器地址,port是服务器端口。然后调用:

socket.send(sendPacket);

就将内容发送出去了,当然相应的网络访问权限得加上。接受数据这么使:

DatagramPacket recvPacket
            = new DatagramPacket(recvBuf , recvBuf.length);
socket.receive(recvPacket);

其中recvBuf是接收需要的数组,recvBuf.length是接收内容的长度。如果接收内容的长度小于udp一包的长度,那么接收到的内容就是被阉割之后的。然后需要将接收和发送的代码封装一下,实现在单独的两个线程中实现接收和发送。接收的话考虑到有可能同时有许多独立的udp数据需要发送,那么就使用同步队列来保持这些要发送的udp包,然后从同步队列中取出数据进行发送。
这时候要接收组播了,又要兼容之前的代码,我是这么实现的:

DatagramSocket  socket = new MulticastSocket();
((MuticastSocket) socket).joinGroup(InetAddress.getByName(GroupIP));

其中GroupIP为组播服务器的地址。这样之后接收和发送的代码均无需修改。

那么问题来了

那么问题真的来了,我手上有三款手机,只有一款手机可以正常接收组播。
然后查询了一些资料,查到得使用MulticastLock。

WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);  
MulticastLock multicastLock = wifiManager  
        .createMulticastLock("multicast.test");  
multicastLock.acquire(); 

还要添加相关权限

然并卵,加上之后接收不到组播的手机仍然接收不到。
同时又发现,通过组播接收到的数据比通过点对点接收的要少,因为我们接收到数据之后会进行校验,组播接收的数据通过校验的成功率要低的多,相同的代码,通过点对点的方式成功率要高的多还稳定。初步估计是手机底层过滤掉了部分数据。
所以大神们,怎么解决这个问题。Who can help me?

你可能感兴趣的:(Android 如何接收组播)