zoukankan      html  css  js  c++  java
  • iOS 支持 IPv6

    苹果的规定:2016年6月1日提交到App Store必须支持IPv6-only网络。

     官方文档:https://developer.apple.com/library/mac/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html#//apple_ref/doc/uid/TP40010220-CH213-SW1

    大多数应用APP 不需要任何改变,因为IPv6的已经被NSURLSession、CFNetwork、NSURLConnection 支持。

    一、是否需要修改代码

    1、如果线上环境的APP 只使用域名访问,没有使用IP地址,并且没有使用底层socket API ,就不用修改代码。

    直接访问IP地址 主要是用在测试环境中。

    大多数app使用的:NSURLSession、NSURLConnection、UIWebView、WKWebView、CFNetwork。所以可以不用修改网络代码,AFNetworking2.x、reachability 这些 都 不用做任何的改变。 

    不过还是 推荐 大家升级AFNetworking到最新版本,毕竟NSURLConnection迟早要被淘汰。

    用Swift写的 就直接用 Alamofire吧。

    2、Reachability不用IP地址,可以固定写死为 线上域名。也可以用 AFNetworking 的Reachability来判断网络连接状态(是异步的,不用输入域名或IP)。

    Reachability 最新版本 官方 声明iOS8以上系统可以使用,经测试,iOS 7.0以上系统都可以使用。

    3、iOS 9.0、OS X 10.11 以上的系统 在IPv6的环境下 是支持IP地址访问网络的。所以大家测试机如果是 iOS9.0以上的系统,可以直接通过IP访问。这是因为iOS 9.0之后 NSURLSession和CFNetwork能把IPv4的地址 合成IPv6的地址(在DNS64/NAT64网络环境中)。

    iOS 9.0以下的系统 就会报错,这和是否升级 AFNetworking 没有关系。就算升级AFNetworking到3.x,也是一样会报:Error Domain=NSURLErrorDomain Code=-1001 等错误。

     官方图片:

     

    4、分享SDK

    微信SDK、新浪微博SDK 都更新了版本,并声明支持IPv6。

    但是因为微信本身不支持IPv6,所以即使更新SDK到最新版本,分享到微信时,在微信的APP 还是会一直显示网络无法连接。

    测试发现,不更新 这些分享的SDK,也能兼容IPv6。(等微信支持IPv6后,是否必须更新SDK 还不清楚)

    友盟分享 官网建议升级SDK,个人也是推荐升级,如果实在不想升,应该也没问题。

    来个小插曲:

    上星期友盟新发的5.2版本 的SDK 有 邮件、短信分享崩溃的bug,给他们提出了。他们昨天下午进行了升级。

     

    二、现有APP支持IPv6的情况

    1、绝大多数 都是支持IPv6的,比如:QQ,淘宝、大众点评。

    1.1、因为绝大多数的app 都使用的域名,而不是ip地址。

    1.2、并且没有调用底层的socket api。

    1.3、不需要进行DNS查找。


    2、极少数app不支持IPv6,比如:微信。

    三、DNS64/ NAT64

     DNS64/ NAT64过渡工作流程:

    1、提供独立的IPv4和IPv6连接 的 蜂窝网络,把IPv4的网络升级到IPv6

     

    上图只是理想状态下,升级到IPv6的情况,但是现在绝大多数都是IPv4的服务器,所以一些大的供应商开始实施DNS64/NAT64 的过度 来支持IPv6.

    2、部署DNS64/NAT64 IPv6的蜂窝网络

    客户端请求 网站域名,首先会通过DNS64服务器 查询该域名是否存在 IPv6的地址,如果存在,就返回IPv6的地址。如果不存在,就去查找该域名对应的IPv4地址,并返回。

    下面是详细流程图:

    3、DNS64/NAT64 转换 流程:

    DNS64/NAT64 可以 将IPv4地址 转换为IPv6,将IPv6地址解析成IPv4。

    IPv4地址 转换为IPv6:
    客户端访问网站域名 ,如果网站只有 IPv4 地址:56.111.211.22,转成16进制: 38 6F D3 16,该16进制为IPv6的最后2位:   64:ff9b::386F:D316

    四、搭建 IPv6 环境

    MAC 的系统为 OS 10.11 及以上系统。

    1、进入MAC 电脑的 “系统偏好设置”--》按住option/alt 键--》 点击 “共享”

    2、选中“创建NAT64网络”,然后打开热点。

    3、手机 连接 热点后,查看网络的 DNS 为:XX:XX:XX:XX:XX:XX ,说明网络为IPv6。

    下图为MAC搭建IPv6 的原理图:

     目前,一个网卡会同时使用这两张地址;以后 一个网卡仅有IPv6 地址。 两种设备不能直接访问,需要DNS64/NAT64 这种 过渡技术才能 互相访问。

    五、升级AFNetworking2.X到最新版本

    1、将  AFHTTPRequestOperationManager 替换为:  AFHTTPSessionManager

    2、将  AFHTTPRequestOperation  替换为:NSURLSessionTask

    3、如果通过IP访问,或者允许https证书之外的域名访问,需要设置 validatesDomainName 为false。

    这个设置是源于 2.5.3版本 之前的安全漏洞(AFNetworking曝SSL漏洞)。

    修改完成后可以使用了,但是很不安全,这样黑客可以获取 你https 通信的数据。无论你是用http还是https,数据一定要加密。。

    AFHTTPSessionManager * manager = [AFHTTPSessionManager manager];
    
    manager.securityPolicy = [AFSecurityPolicy defaultPolicy];
    
    manager.securityPolicy.allowInvalidCertificates = YES;  //忽略https证书
    
    manager.securityPolicy.validatesDomainName = NO;    //是否验证域名

    六、系统兼容IPv6代码

    1、下面的方法 只适用于IPv4,不能兼容IPv6:

    • inet_addr()

    • inet_aton()

    • inet_lnaof()

    • inet_makeaddr()

    • inet_netof()

    • inet_network()

    • inet_ntoa()

    • inet_ntoa_r()

    • bindresvport()

    • getipv4sourcefilter()

    • setipv4sourcefilter()

    2、如果有以下代码处理IPv4类型,要确保IPv6的形式也被处理过:

    IPv4

    IPv6

    AF_INET

    AF_INET6

    PF_INET

    PF_INET6

    struct in_addr

    struct in_addr6

    struct sockaddr_in

    struct sockaddr_in6

    kDNSServiceProtocol_IPv4

    kDNSServiceProtocol_IPv6


    3、使用系统API合成IPv6:

    如果你的APP需要连接的服务器 只有IPv4地址,没有域名,可以用 getaddrinfo 来解决。下面的代码,将IPv4地址(如:192.0.2.1) 地址转换为IPv6地址(如:包含  64:ff9b::192.0.2.1  的struct sockaddr_in6 )

    #include <sys/socket.h>
    
    #include <netdb.h>
    
    #include <arpa/inet.h>
    
    #include <err.h>
    
     
    
     
    
        uint8_t ipv4[4] = {192, 0, 2, 1};
    
        struct addrinfo hints, *res, *res0;
    
        int error, s;
    
        const char *cause = NULL;
    
        
    
        char ipv4_str_buf[INET_ADDRSTRLEN] = { 0 };
    
        const char *ipv4_str = inet_ntop(AF_INET, &ipv4, ipv4_str_buf, sizeof(ipv4_str_buf));
    
        
    
        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));
    
            /*NOTREACHED*/
    
        }
    
        s = -1;
    
        for (res = res0; res; res = res->ai_next) {
    
            s = socket(res->ai_family, res->ai_socktype,
    
                       res->ai_protocol);
    
            if (s < 0) {
    
                cause = "socket";
    
                continue;
    
            }
    
            
    
            if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
    
                cause = "connect";
    
                close(s);
    
                s = -1;
    
                continue;
    
            }
    
            
    
            break;  /* okay we got one */
    
        }
    
        if (s < 0) {
    
            err(1, "%s", cause);
    
            /*NOTREACHED*/
    
        }
    
        freeaddrinfo(res0);

    欢迎关注我的 今日头条号 名称: 云端梦想科技  

    欢迎关注我的 微信公众号:dreams2999

  • 相关阅读:
    丘先生为世界华裔数学家大会(北京 1998)而作
    获取IFC构件的位置数据、方向数据
    TeslaManage运行日志 (201910-201911)
    IFC构件位置数据与revit模型中对应构件位置数据对比
    IFC构件位置信息—ObjectPlacement
    jsoup爬取某网站安全数据
    Java统计文件数量
    osg 渲染ifc数据-测试
    编译日志—20191101
    Tekla 导出ifc并浏览
  • 原文地址:https://www.cnblogs.com/dahe007/p/5527086.html
Copyright © 2011-2022 走看看