• iOS 解决ipv6问题


    解决ipv6的方法有很多种,由于现在国内的网络运营商还在使用ipv4的网络环境,所以appstore应用不可能大范围去修改自己的服务器,

    而且国内的云服务器几乎没有ipv6地址。

    这里附上苹果开发平台提供的解决方案地址:url

    苹果审核ipv6的标准是应用在ipv6的网络环境下和最新的ios系统下,应用也能正常连接。 但是ipv6的客户端是不能直接连接ipv4的服务端,

    需要通过DNS64或者NAT64的转换地址才能连接,下图是连接的处理过程,

     

    DNS64/NAT64是苹果提供的转换通道,不需要开发者去考虑这个问题,所以苹果应用审核只要求开发者不要在底层写死ipv4的通讯api,要兼容ipv6的

    网络环境即可。

    以下是我通过getaddrinfo的api将ipv4转换成ipv6的的过程,并且判断当前环境网络环境去开启相应的ip网络协议的实现:

     1 #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
     2 #include <sys/socket.h>
     3 #include <netdb.h>
     4 #include <arpa/inet.h>
     5 #include <err.h>
     6 
     7 #define CopyString(temp) (temp != NULL)? strdup(temp):NULL
     8 const char* getIPV6(const char * mHost) {
     9     if(mHost == NULL)
    10         return NULL;
    11     struct addrinfo* res0;
    12     struct addrinfo hints;
    13     struct addrinfo* res;
    14     
    15     memset(&hints, 0, sizeof(hints));
    16     
    17     hints.ai_flags = AI_DEFAULT;
    18     hints.ai_family = PF_UNSPEC;
    19     hints.ai_socktype = SOCK_STREAM;
    20     
    21     int n;
    22     if((n = getaddrinfo(mHost, "http", &hints, &res0)) != 0)
    23     {
    24         printf("getaddrinfo failed %d", n);
    25         return NULL;
    26     }
    27     
    28     struct sockaddr_in6* addr6;
    29     struct sockaddr_in * addr;
    30     const char* pszTemp;
    31     
    32     for(res = res0; res; res = res->ai_next)
    33     {
    34         char buf[32];
    35         if(res->ai_family == AF_INET6)
    36         {
    37             addr6 = (struct sockaddr_in6*)res->ai_addr;
    38             pszTemp = inet_ntop(AF_INET6, &addr6->sin6_addr, buf, sizeof(buf));
    39         }
    40         else
    41         {
    42             addr = (struct sockaddr_in*)res->ai_addr;
    43             pszTemp = inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf));
    44         }
    45         
    46         break;
    47     }
    48     
    49     freeaddrinfo(res0);
    50     printf("getaddrinfo ok %s
    ", pszTemp);
    51     return CopyString(pszTemp);
    52 }
    53 
    54 #endif

    在ios 9.2版本系统后,通过getaddrinfo转换ipv4得到ipv6地址(这里我也被坑过了低版本的系统转换不了ipv6,想测试只能升级系统),获得ipv6地址后,可以判断

    地址字符串是否用“:” 来确定使用哪一种socket的通讯方式,判断方法:std::strdchr(const char* value, const char* subStr),如果是NULL,则使用ipv4 socket连接

     if(strchr(addr, ':') != NULL)
            ivp6处理
     else
           ivp4处理

    这样一来就不会写死通讯协议。

    我这里还遇到一个坑,内网的访问下是不可能连接到自己的服务器,后面测试一下公网阿里云的服务器,能够正常连接,这个可能是DNS64在搜索ipv6的过程中,并

    没有搜索内网的网络,导致内网连接失败(这里卡了半天, 切记)

    转载请注明出处,from 博客园HemJohn

  • 相关阅读:
    javascript之this的深入学习
    记一次前端面试
    nodejs学习
    Javascript内置对象
    Javascript事件
    全屏滚动插件小结
    Javascript函数的深入学习
    近年来前端开发趋势,MVVM框架,Vue.js的核心思想
    Javascript的for ... in循环
    JavaScript的对象深入学习
  • 原文地址:https://www.cnblogs.com/HemJohn/p/5590483.html
Copyright © 2020-2023  润新知