本文主要功能是多台Android设备使用组播在局域网下通讯。本文为在IPv4下的。
一、获取组播地址并且joinGroup:
private InetAddress broadcastAddress;
private void initCast() {
try {
broadcastAddress = IpUtils.getBroadcastAddress();
multicastSocket = new MulticastSocket(7878);
multicastSocket.joinGroup(broadcastAddress);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static InetAddress getBroadcastAddress()
throws IOException {
// 获取本地所有网络接口
Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface networkInterface = interfaces.nextElement();
if (networkInterface.isLoopback() || !networkInterface.isUp()) {
continue;
}
// getInterfaceAddresses()方法返回绑定到该网络接口的所有 IP 的集合
for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) {
InetAddress broadcast = interfaceAddress.getBroadcast();
if (broadcast == null) {
continue;
}
return broadcast;
}
}
return null;
}
二、发送与接受数据。
private void receiverData() {
new Thread(){
public void run(){
try {
byte[] data = new byte[125];
pack = new DatagramPacket(data, data.length);
multicastSocket.receive(pack);
Log.i(TAG, "receiverData---"+Arrays.toString(data));//show data
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
private void sendData() {
new Thread(){
public void run(){
try {
byte[] data = "来了,老弟!".getBytes();
DatagramPacket pack = new DatagramPacket(data, data.length, broadcastAddress,7878);
multicastSocket.send(pack);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
三、以上代码在多台Android设备连接同一WiFi下可行,但是有些手机可以开热点的同时连接WiFi(比如一些小米手机),这个时候可能就会出现问题。解决办法:发现同时开热点连接WiFi会有两个组播地址、两个IP地址;只需要加入组的时候将两个组播地址都加入组,并且发送数据的时候两个组都发送。看代码:
private List listAddress;
private void initCastT() {
try {
listAddress = IpUtils.getListBroadcastAddress();
multicastSocket = new MulticastSocket(7878);
try {//此处单独try是应为这里会抛异常,防止导致下面代码运行不到。
multicastSocket.joinGroup(listAddress.get(0));
} catch (Exception e) {
// TODO: handle exception
}
if (listAddress.size() == 2) {
try {
multicastSocket.joinGroup(listAddress.get(1));
} catch (Exception e) {
// TODO: handle exception
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void sendDataT() {
new Thread(){
public void run(){
try {
byte[] data = "来了,老弟!".getBytes();
DatagramPacket pack = new DatagramPacket(data, data.length, listAddress.get(0),7878);
multicastSocket.send(pack);
if (listAddress.size() == 2) {
DatagramPacket pack1 = new DatagramPacket(data, data.length, listAddress.get(1),7878);
multicastSocket.send(pack);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
public static List getListBroadcastAddress()throws IOException {
// 获取本地所有网络接口
List addList = new ArrayList();
Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface networkInterface = interfaces.nextElement();
if (networkInterface.isLoopback() || !networkInterface.isUp()) {
continue;
}
// getInterfaceAddresses()方法返回绑定到该网络接口的所有 IP 的集合
for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) {
InetAddress broadcast = interfaceAddress.getBroadcast();
if (broadcast == null) {
continue;
}
addList.add(broadcast);
}
}
return addList;
}
private void receiverData() {
new Thread(){
public void run(){
try {
while(true){
byte[] data = new byte[125];
pack = new DatagramPacket(data, data.length);
multicastSocket.receive(pack);
Log.i(TAG, "receiverData---"+Arrays.toString(data));// show receiver data
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
最后,代码仅供大家参考,如有错误请帮忙指出,谢谢!