IOS开发资料库真机相关iOS进阶指南

iOS 支持IPv6-Only网络资料整理

2016-07-31  本文已影响1670人  HK_Hank

导语:

自从5月初Apple明文规定所有开发者在6月1号以后提交新版本需要支持IPV6-Only的网络。自从苹果实施以来,也遇到了各种各样的问题,现此把知道的资料整理一下

首先,说明一下什么是IPv6

IPv6是Internet Protocol Version 6的缩写,其中Internet Protocol译为“互联网协议”。IPv6是IETF(互联网工程任务组,Internet Engineering Task Force)设计的用于替代现行版本IP协议(IPv4)的下一代IP协议,号称可以为全世界的每一粒沙子编上一个网址[1]。

为什么用IPv6?

由于IPv4最大的问题在于网络地址资源有限,严重制约了互联网的应用和发展。IPv6的使用,不仅能解决网络地址资源数量的问题,而且也解决了多种接入设备连入互联网的障碍。
与IPv4相比,IPv6具有更大的地址空间。IPv4中规定IP地址长度为32,最大地址个数为232;而IPv6中IP地址的长度为128,即最大地址个数为2128。与32位地址空间相比,其地址空间增加了2128-232个。
其他优势,请大家自行Google。

IPv6地址是什么样的?

IPv6地址格式为X:X:X:X:X:X:X:X,其中每个X表示地址中的16b,以十六进制表示,例如:ABCD:EF01:2345:6789:ABCD:EF01:2345:6789

苹果指的IPv6-Only网络是什么?

IPv6 DNS64/NAT64网络即是所谓的IPV6-Only网络,该网络可以通过转换的方式来继续访问IPv4地址。

IPv6 DNS64/NAT64网络是什么?

可以通过以下流程图和时序图来了解


NAT流程
IPv6 DNS64/NAT64网络下IPv6地址与IPv4地址交互的时序图
其中

DNS(Domain Name System,域名系统),通过DNS服务器,解析域名为IP地址
NAT(Network Address Translation,网络地址转换),内网IP地址到外网IP地址的转换

我现在是IPv4网络环境,我该怎么测试IPv6网络呢?

苹果提供了一个搭建虚拟IPv6 DNS64/NAT64网络的方法,要求Mac设备在Mac OS 10.11以上系统,通过有线网开一个IPv6-Only网络的热点,原理图如下:


Paste_Image.png Paste_Image.png Paste_Image.png Paste_Image.png Paste_Image.png Paste_Image.png Paste_Image.png Paste_Image.png

出现以下图片,即热点开成功了


Paste_Image.png

Apple如何审核支持IPV6-Only?

经过查阅相关资料和上传的版本来看,苹果审核的时候使用最新的系统(目前是IOS9.3.2)来测试IPv6-Only网络的,应该是在该网络下可以正常使用即可。并不会扫描应用内IPv4专有的底层API。

Note: In iOS 9 and OS X 10.11 and later, NSURLSession and CFNetwork automatically synthesize IPv6 addresses from IPv4 literals locally on devices operating on DNS64/NAT64 networks. However, you should still work to rid your code of IP address literals.

对于使用了写死IPv4地址来交互的朋友。苹果提到,在iOS9以上的系统,苹果自己会做IPv4转IPv6地址的转换,所以如果应用中写死的IPv4地址,并且是使用NSURLSession and CFNetwork(测试发现NSURLConnection也是可以的)来做网络请求,则在IOS9以上系统,还是可以在IPv6-Only网络正常运行的,所以是可以通过审核的之后可能还是有风险,建议还是换成域名)。

应用如何支持IPV6-Only?

iOS中将IPv4地址转换为IPv6地址

在iOS 9.2版本系统后,通过getaddrinfo转换ipv4得到ipv6地址,该方法只能在iOS9.2以后才有效。
OC代码

#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <err.h>

#define CopyString(temp) (temp != NULL)? strdup(temp):NULL
- (NSString *)getIPAddress:(NSString *)ipAddress {
    if (!ipAddress) {
        return @"";
    }

    struct addrinfo hints, *res, *res0;
    int error;

    const char *ipv4_str = [ipAddress UTF8String];
    
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_DEFAULT;
    error = getaddrinfo(ipv4_str, "http", &hints, &res0);
    if (error) {
        errx(1, "%s", gai_strerror(error));
        return @"";
    }
    
    struct sockaddr_in6* addr6;
    struct sockaddr_in * addr;
    const char* pszTemp;
    
    for (res = res0; res; res = res->ai_next) {
        char buf[32];
        if(res->ai_family == AF_INET6) {
            addr6 = (struct sockaddr_in6*)res->ai_addr;
            pszTemp = inet_ntop(AF_INET6, &addr6->sin6_addr, buf, sizeof(buf));
        } else {
             addr = (struct sockaddr_in*)res->ai_addr;
             pszTemp = inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf));
        }

        break;
    }
    
    freeaddrinfo(res0);
    printf("getaddrinfo ok %s\n", pszTemp);
    return [NSString stringWithFormat:@"%s",CopyString(pszTemp)];
}

C++代码可以参照:
iOS 解决ipv6问题

上一篇下一篇

猜你喜欢

热点阅读