Android ipv6 使用组播在局域网下通讯。

随着移动设备的增多,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 (Enumeration en = NetworkInterface
                    .getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration enumIpAddr = 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 (Enumeration en = NetworkInterface
                    .getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration enumIpAddr = 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单播地址 (包括链路本地单播地址 和 站点本地单播地址)。

 

你可能感兴趣的:(Android ipv6 使用组播在局域网下通讯。)