Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 452|回复: 0

【转】iOS 解决ipv6问题

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-5-24 05:22:14 | 显示全部楼层 |阅读模式

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

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

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

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

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

     

     

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

    网络环境即可。

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

    #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    #include <sys/socket.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    #include <err.h>
    
    #define CopyString(temp) (temp != NULL)? strdup(temp):NULL
    const char* getIPV6(const char * mHost) {
        if(mHost == NULL)
            return NULL;
        struct addrinfo* res0;
        struct addrinfo hints;
        struct addrinfo* res;
        
        memset(&hints, 0, sizeof(hints));
        
        hints.ai_flags = AI_DEFAULT;
        hints.ai_family = PF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        
        int n;
        if((n = getaddrinfo(mHost, "http", &hints, &res0)) != 0)
        {
            printf("getaddrinfo failed %d", n);
            return NULL;
        }
        
        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 CopyString(pszTemp);
    }
    
    #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

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-19 19:31 , Processed in 0.062443 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表