安卓地址。getAllByName()仅接收带有java的IPv4地址。网首选IPv6地址
tl;dr
InetAddress.getAllByName()
仅接收IPv4地址列表,即使在NAT64网络和iOS设备上java.net.preferIPv6Addresses
设置为true时也是如此。同样的代码在连接到同一网络的安卓上也能正常工作
这意味着在纯ipv6网络中(根据苹果商店的要求),任何试图建立HttpURLConnection的应用程序都将失败,并将被苹果拒绝
原始帖子
我正在用Java为iOS创建一个应用程序,我使用HttpsURLConnection
连接到服务器,在NAT64网络上进行测试之前,一切正常。苹果审查小组拒绝了该应用程序,因此我正在使用NAT64网络进行本地测试
要创建NAT64网络,请执行以下步骤:Supporting IPv6 DNS64/NAT64 Networks
示例代码:
HttpsURLConnection testConn = null;
try {
URL testUrl = new URL("https://google.com");
testConn = (HttpsURLConnection) testUrl.openConnection();
testConn.connect();
}catch (Exception e){
e.printStackTrace();
}finally {
if(testConn != null){
testConn.disconnect();
}
}
在我的NAT64网络上,此代码因java.net.SocketException: Network is unreachable
而失败
我已尝试更改系统属性:
System.setProperty("java.net.preferIPv4Stack", "false");
System.setProperty("java.net.preferIPv6Addresses", "true");
我还尝试将网站设置为我们的服务器以外的其他内容(如google.com的测试代码所示)。我还使用wireshark嗅探了来自wi-fi连接的数据包,唯一的流量是谷歌的DNS请求。com似乎没有失败。最后,我还尝试返回到HttpURLConnection
,以防问题与HTTPS有关
另外值得注意的是,测试版iPhone上的safari可以轻松访问我们所有的服务器和域,而且该设备似乎具有稳定且功能强大的互联网连接。当我的安卓设备连接到同一个NAT64网络时,该应用程序也会失败
编辑:
设置System.setProperty("java.net.preferIPv6Addresses", "true");
解决了安卓上的问题,因此现在这个问题与我在NAT64网络上的iPhone5无关。在这个阶段,我的最佳猜测是该属性正在被另一个类设置,并且被忽略。我曾尝试在类顶部的静态初始值设定项块中设置该属性,但没有效果
编辑2:
我使用了System.getProperty("java.net.preferIPv6Addresses")
,它在iPhone5上返回true
,所以它肯定被设置好了,让我再次感到困惑
编辑3:
我深入研究了HttpsURLConnection
,它实现了一个PlainSocketImpl
类来处理其连接,该类使用InetAddress
。我决定测试一个InetAddress
,当我在iPhone上调用InetAddress.getByName("google.com")
时,我得到一个ipv4地址,而在安卓上它返回一个ipv6地址。似乎iOS上忽略了属性java.net.preferIPv6Addresses
。我已经尝试将JDK更新到最新版本,但这没有帮助
我还尝试了InetAddress.getAllByName("www.google.com")
,它只在iPhone上返回IPv4地址。我想说,这显然是一个DNS问题,但为什么在连接到同一网络的安卓上这不是一个问题呢
因此,我现在知道问题是什么,但不知道如何解决它
# 1 楼答案
解决方案是将我的应用程序升级为在最新版本的MAF上运行
详情:
尽管我已将Eclipse和MAF更新为最新版本,但我的应用程序仍将其原始MAF版本用作目标运行时。我通过查看我的目标SDK发现了这一点,并意识到我无法更改运行时verison
要进行更新,我必须创建一个新项目,确保将目标运行时设置为MAF的最新版本。然后,我将代码迁移到这个新项目,并能够在仅限IPv6的网络下成功运行我的应用程序
(在撰写本文时,MAF 2.3.2是可用于Eclipse的最新版本)
如果有一种方法可以在不创建新项目的情况下做到这一点,我就无法发现它