随着移动设备的增多,Ipv4已经开始不能满足地址需求,有些移动设备开始放弃Ipv4,只能使用Ipv6。因此对Ipv6的兼容至关重要。因为项目的需要,这几天我了解了Android 对Ipv6的兼容。
一、将组播地址 joinGroup 到组。
private static final String IPV6_BROADCAST_ADDR = "FF02::1";
private void initNetGroup(Context mContext) {
//if (multicastSocket != null) {
//multicastSocket.close();
//multicastSocket = null;
//}
try {
multicastSocket = new MulticastSocket(7878);
} catch (IOException e) {
e.printStackTrace();
}
try {
multicastSocket.setNetworkInterface(IpUtils.getIpv6NetworkInterface());
} catch (SocketException e1) {
e1.printStackTrace();
}
InetSocketAddress socketAddress = null;
try {
socketAddress = new InetSocketAddress(InetAddress.getByName(IPV6_BROADCAST_ADDR), 7878);
} catch (UnknownHostException e1) {
e1.printStackTrace();
}
try {
multicastSocket.joinGroup(socketAddress, IpUtils.getIpv6NetworkInterface());
} catch (IOException e) {
e.printStackTrace();
}
}
二、这里使用了所有节点组播地址FF02::1,使用Ipv6组播一点要设置NetworkInterface,下面是NetworkInterface的获取方法:
public static NetworkInterface getIpv6NetworkInterface() {
try {
for (Enumerationen = NetworkInterface
.getNetworkInterfaces(); en.hasMoreElements(); ) {
NetworkInterface intf = en.nextElement();
for (EnumerationenumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumIpAddr.nextElement();
// logger.error("ip1 " + inetAddress);
String hostAddress = inetAddress.getHostAddress();
LogUtils.i("hdb2 " + hostAddress);
if (inetAddress instanceof Inet6Address) {//ipv6
if (!hostAddress.startsWith("fe") && !hostAddress.startsWith("fc") && hostAddress.length() > 6) {
LogUtils.i("hdb2---ipv6:" + hostAddress);
return intf;
}
}else {//ipv4
//if (!"127.0.0.1".equalsIgnoreCase(hostAddress)) {
//LogUtils.i("hdb2---ipv4:" + hostAddress);
//return inetAddress;
//}
}
}
}
} catch (Exception ex) {
Log.e("IP Address", ex.toString());
}
return null;
}
三、要使用Ipv6,一定要设备分配了ipv6地址,需要注意的是以FE、FC开头的是本地用IPV6单播地址 (包括链路本地单播地址 和 站点本地单播地址)。
四、接收发送数据跟Ipv4没有区别:
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();
}
private void sendData() {
new Thread(){
public void run(){
try {
byte[] data = "来了,老弟!".getBytes();
DatagramPacket pack = new DatagramPacket(data, data.length, InetAddress.getByName(IPV6_BROADCAST_ADDR),7878);
multicastSocket.send(pack);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
五、ipv6地址获取:
public static InetAddress getLocalIp() {
try {
for (Enumerationen = NetworkInterface
.getNetworkInterfaces(); en.hasMoreElements(); ) {
NetworkInterface intf = en.nextElement();
for (EnumerationenumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumIpAddr.nextElement();
// logger.error("ip1 " + inetAddress);
String hostAddress = inetAddress.getHostAddress();
LogUtils.i("hdb2 " + hostAddress);
if (inetAddress instanceof Inet6Address) {//ipv6
if (!hostAddress.startsWith("fe") && !hostAddress.startsWith("fc") && hostAddress.length() > 6) {
LogUtils.i("hdb2---ipv6:" + hostAddress);
return inetAddress;
}
}else {//ipv4
if (!"127.0.0.1".equalsIgnoreCase(hostAddress)) {
LogUtils.i("hdb2---ipv4:" + hostAddress);
return inetAddress;
}
}
}
}
} catch (Exception ex) {
Log.e("IP Address", ex.toString());
}
return null;
}
六、获取到ipv6地址后,可以将地址通过组播的方式发送到局域网中的其他设备;其他设备收到地址后,可以通过TCP的方式来连接设备,连接方式跟Ipv4是一样的,这里就不贴代码了。主要是确保ipv6地址不是本地用IPV6单播地址 (包括链路本地单播地址 和 站点本地单播地址)。