安卓应用程序如何支持 IPv6 安卓应用程序如何支持 IPv6
这个问题我足足研究了两天,才有了一点思路,现在我把我的心路历程写下来,给大家分享下23.
1.什么是ipv6,自己百度
2,它和ipv4的区别,也是没啥用自己搜
3.app怎么适配ipv6.
首先访问接口使用域名,而不是ip格式.
其次在app当中获取手机ip的时候不要使用网上搜的正则表达式,因为ipv6和v4 格式不一样,会报错,
最后网络访问框架最好用主流框架,不要修改底层网络接口配置,(如果你不是大神,你也不会改)
4.app怎么测试?
第一次尝试:
搭建ipv6热点,Windows搭建太复杂,没学会,只能用mac去搭建,但是搭建好的wifi
只能用iPhone链接测试,安卓不能用,原因安卓手机没有ipv6的dhcp不能自动获得ipv6的地址,所以这种思路到这里就结束了,
第二次尝试:
购买ipv6华为路由器,没钱,这种思路结束
第三次尝试:
偶然看见手机可以选择apn接入点,至于apn接入点怎么修改,你自己搜搜很容易
https://zhidao.baidu.com/question/537943311.html 里面有三个选项:
ipv4 , ipv6, Ipv4和ipv6我反复测试,
测试手机访问使用的地址给大家提供下:http://ip4only.me/ http://ip6only.me和http://ip6.me/第一个网址只支持ipv4,第二个网址只支持ipv6访问,第三个是都支持
测试结果:
1.如果我修改的Ipv4接入点和漫游点::Ipv4only是v4地址. ipv6only是访问不到..都支持的是v4地址.
2.如果我修改的Ipv6接入点和漫游点::Ipv4only是v4地址. ipv6only是v6..都支持的是v6地址.
3..如果我修改的Ipv4Ipv6接入点和漫游点::Ipv4only是v4地址. ipv6only是v6..都支持的是v6地址.
4.如果我修改的Ipv4接入点和v6漫游点::Ipv4only是v4地址. ipv6only是v6..都支持的是v6地址.
5.如果我修改的Ipv4接入点和v4v6漫游点::Ipv4only是v4地址. ipv6only是v6..都支持的是v6地址.
6.如果我修改的Ipv6接入点和v4漫游点::Ipv4only是v4地址. ipv6onlyv6..都支持的是v6地址.
还有很多情况我就不一一列举了,反正这就告诉我们,这个方式不行,究竟谁负责啥,哪位大神可以跟我说下就好了,哎可惜我没查到到底在怎么配置,因为现在我们后台是ipv4only,所以我们无论怎么设置访问时候都是ipv4的地址,
那么到底有没有办法呢
有,设置你app的网络访问框架,仅仅支持ipv4或者ipv6或者啥都支持,
怎么弄呢?我是上代码大家自己看吧23
public class DnsSelector implements Dns {
public enum Mode {
SYSTEM,
IPV6_FIRST,
IPV4_FIRST,
IPV6_ONLY,
IPV4_ONLY
}
private Map<String, List<InetAddress>> overrides = Maps.newHashMap();
private Mode mode;
public DnsSelector(Mode mode) {
this.mode = mode;
}
public static Dns byName(String ipMode) {
Mode selectedMode;
switch (ipMode) {
case "ipv6":
selectedMode = Mode.IPV6_FIRST;
break;
case "ipv4":
selectedMode = Mode.IPV4_FIRST;
break;
case "ipv6only":
selectedMode = Mode.IPV6_ONLY;
break;
case "ipv4only":
selectedMode = Mode.IPV4_ONLY;
break;
default:
selectedMode = Mode.SYSTEM;
break;
}
return new DnsSelector(selectedMode);
}
@SuppressLint("NewApi")
@Override
public List<InetAddress> lookup(String hostname) throws UnknownHostException {
List<InetAddress> addresses = overrides.get(hostname.toLowerCase());
if (addresses != null) {
return addresses;
}
addresses = Dns.SYSTEM.lookup(hostname);
switch (mode) {
case IPV6_FIRST:
addresses.sort(Comparator.comparing(Inet4Address.class::isInstance));
break;
case IPV4_FIRST:
addresses.sort(Comparator.comparing(Inet4Address.class::isInstance).reversed());
break;
case IPV6_ONLY:
addresses = addresses.stream().filter(Inet6Address.class::isInstance).collect(toList());
break;
case IPV4_ONLY:
addresses = addresses.stream().filter(Inet4Address.class::isInstance).collect(toList());
break;
}
return addresses;
}
public void addOverride(String hostname, InetAddress address) {
overrides.put(hostname.toLowerCase(), Lists.newArrayList(address));
}
}
okhttp初始化的时候,传入标记位即可,实现想要的网络访问模式.
okHttpClient = new OkHttpClient.Builder()
.eventListenerFactory(NetWorkEventListener.FACTORY)
.dns(new DnsSelector(IP_SELECTOR_MODE))
.build();
如果您有更好的办法,请告我我,感激不尽08
就是搭建一个安卓可以用的wifi热点而已,