当前位置: 首页 > news >正文

iOS 应用将适应新的的IPv6-only网络 -解决方案

苹果公司还称“在WWDC 2015上,我们宣布iOS 9开始向IPv6-only网络服务过渡。自2016年6月1日起,开发者所有提交至App Store的应用必须支持IPv6-only网络。由于大部分现有应用程序已经通过NSURLSession和CFNetwork APIs兼容该协议,因此这些应用无需做出调整。但如果你依然使用IPv4 API的或者硬件编码IP地址,那么你需要手动调整应用代码来适应新变化。”

  除此之外,苹果还提供了相关资料,帮助开发者开始向已经添加了对IPv6-only网络的支持过渡,其中包括了WWDC 2015大会期间的开发者文档等。

 [摘录自:http://mt.sohu.com/20160520/n450596544.shtml]


一般的http请求不受影响,但如果使用socket等则需要调整.经测试,目前支付宝,微信均在ipv6下不能正常访问网络.QQ客户端可以.

由于公司项目中使用了CocoaAsyncSocket,经测试,公司的app在ipv6下不能使用.


解决方案:针对ios9做单独处理.

经修改后,测试ios9可以正常使用.



下面是修改:

1,AFNetworkReachabilityManager

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. + (instancetype)manager  
  2. {  
  3. //#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)  
  4. //    struct sockaddr_in6 address;  
  5. //    bzero(&address, sizeof(address));  
  6. //    address.sin6_len = sizeof(address);  
  7. //    address.sin6_family = AF_INET6;  
  8. //#else  
  9. //      
  10. //    struct sockaddr_in address;  
  11. //    bzero(&address, sizeof(address));  
  12. //    address.sin_len = sizeof(address);  
  13. //    address.sin_family = AF_INET;  
  14. //#endif  
  15.       
  16.       
  17.     if (IOS9)  
  18.     {  
  19.         struct sockaddr_in6 address;  
  20.         bzero(&address, sizeof(address));  
  21.         address.sin6_len = sizeof(address);  
  22.         address.sin6_family = AF_INET6;  
  23.         return [self managerForAddress:&address];  
  24.     }  
  25.     else  
  26.     {  
  27.         struct sockaddr_in address;  
  28.         bzero(&address, sizeof(address));  
  29.         address.sin_len = sizeof(address);  
  30.         address.sin_family = AF_INET;  
  31.         return [self managerForAddress:&address];  
  32.     }  
  33. }  


2,GCDAsyncSocket使用

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. GCDAsyncSocket *socketTest = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];  
  2. if(IOS9)  
  3. {  
  4.    socketTest.IPv4PreferredOverIPv6 = NO;  
  5. }  
  6. [socketTest connectToHost:@"xxx.xxx.xxx.xxx" onPort:xxx withTimeout:20 error:nil];  

3,GCDAsyncSocket.m

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. + (NSMutableArray *)lookupHost:(NSString *)host port:(uint16_t)port error:(NSError **)errPtr  
  2. {  
  3.     LogTrace();  
  4.       
  5.     NSMutableArray *addresses = nil;  
  6.     NSError *error = nil;  
  7.       
  8.     if ([host isEqualToString:@"localhost"] || [host isEqualToString:@"loopback"])  
  9.     {  
  10.         // Use LOOPBACK address  
  11.         struct sockaddr_in nativeAddr4;  
  12.         nativeAddr4.sin_len         = sizeof(struct sockaddr_in);  
  13.         nativeAddr4.sin_family      = AF_INET;  
  14.         nativeAddr4.sin_port        = htons(port);  
  15.         nativeAddr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);  
  16.         memset(&(nativeAddr4.sin_zero), 0, sizeof(nativeAddr4.sin_zero));  
  17.           
  18.         struct sockaddr_in6 nativeAddr6;  
  19.         nativeAddr6.sin6_len        = sizeof(struct sockaddr_in6);  
  20.         nativeAddr6.sin6_family     = AF_INET6;  
  21.         nativeAddr6.sin6_port       = htons(port);  
  22.         nativeAddr6.sin6_flowinfo   = 0;  
  23.         nativeAddr6.sin6_addr       = in6addr_loopback;  
  24.         nativeAddr6.sin6_scope_id   = 0;  
  25.           
  26.         // Wrap the native address structures  
  27.           
  28.         NSData *address4 = [NSData dataWithBytes:&nativeAddr4 length:sizeof(nativeAddr4)];  
  29.         NSData *address6 = [NSData dataWithBytes:&nativeAddr6 length:sizeof(nativeAddr6)];  
  30.           
  31.         addresses = [NSMutableArray arrayWithCapacity:2];  
  32.         [addresses addObject:address4];  
  33.         [addresses addObject:address6];  
  34.     }  
  35.     else  
  36.     {  
  37.         NSString *portStr = [NSString stringWithFormat:@"%hu", port];  
  38.           
  39.         struct addrinfo hints, *res, *res0;  
  40.           
  41.         memset(&hints, 0, sizeof(hints));  
  42.         hints.ai_family   = PF_UNSPEC;  
  43.         hints.ai_socktype = SOCK_STREAM;  
  44.         hints.ai_protocol = IPPROTO_TCP;  
  45.           
  46.         int gai_error = getaddrinfo([host UTF8String], [portStr UTF8String], &hints, &res0);  
  47.           
  48.         if (gai_error)  
  49.         {  
  50.             error = [self gaiError:gai_error];  
  51.         }  
  52.         else  
  53.         {  
  54.             NSUInteger capacity = 0;  
  55.             for (res = res0; res; res = res->ai_next)  
  56.             {  
  57.                 if (res->ai_family == AF_INET || res->ai_family == AF_INET6) {  
  58.                     capacity++;  
  59.                 }  
  60.             }  
  61.               
  62.             addresses = [NSMutableArray arrayWithCapacity:capacity];  
  63.               
  64.             for (res = res0; res; res = res->ai_next)  
  65.             {  
  66.                 if (res->ai_family == AF_INET)  
  67.                 {  
  68.                     // Found IPv4 address.  
  69.                     // Wrap the native address structure, and add to results.  
  70.                       
  71.                     if (((struct sockaddr_in *)res->ai_addr)->sin_port == 0)  
  72.                         ((struct sockaddr_in *)res->ai_addr)->sin_port = htons(port);  
  73.                     NSData *address4 = [NSData dataWithBytes:res->ai_addr length:res->ai_addrlen];  
  74.                     [addresses addObject:address4];  
  75.                 }  
  76.                 else if (res->ai_family == AF_INET6)  
  77.                 {  
  78.                     // Found IPv6 address.  
  79.                     // Wrap the native address structure, and add to results.  
  80.                       
  81.                     struct sockaddr_in6 *sockaddr = (struct sockaddr_in6 *)res->ai_addr;  
  82.                     sockaddr->sin6_port = htons(port);  
  83.                       
  84.                     NSData *address6 = [NSData dataWithBytes:res->ai_addr length:res->ai_addrlen];  
  85.                     [addresses addObject:address6];  
  86.                       
  87. //                    if (((struct sockaddr_in6 *)res->ai_addr)->sin6_port == 0)  
  88. //                        ((struct sockaddr_in6 *)res->ai_addr)->sin6_port = htons(port);  
  89. //                    NSData *address6 = [NSData dataWithBytes:res->ai_addr length:res->ai_addrlen];  
  90. //                    [addresses addObject:address6];  
  91.                 }  
  92.             }  
  93.   
  94.             freeaddrinfo(res0);  
  95.               
  96.             if ([addresses count] == 0)  
  97.             {  
  98.                 error = [self gaiError:EAI_FAIL];  
  99.             }  
  100.         }  
  101.     }  
  102.       
  103.     if (errPtr) *errPtr = error;  
  104.     return addresses;  
  105. }  

from:http://blog.csdn.net/james_1010/article/details/51507269
http://www.codeinsect.net/blog/2016/05/26/unity-ipv6-socket-%E6%94%AF%E6%8C%81%EF%BC%8C%E5%B7%B2%E6%B5%8B%E8%AF%95%E9%80%9A%E8%BF%87/



相关资料:

CocoaAsyncSocket相关解决方案:https://github.com/robbiehanson/CocoaAsyncSocket/issues/429

apple开发文档:https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html


相关文章:

  • iOS 开发怎么入门?
  • 如何在Mac OS X上安装 Ruby运行环境
  • iOS CocoaPods安装和使用图解
  • Github上600多个iOS开源项目分类及介绍
  • 使用CocoaPods找不到头文件解决方法
  • 用xib设置圆角,边框和UITextField的私有属性placeholderColor
  • 定制全局的导航栏样式
  • 整理 iOS 9 适配中出现的坑(图文)
  • iOS 应用修改状态栏和导航栏颜色
  • AFNetworking3.1 基本使用
  • Xib使用之TableViewCell.xib中创建多个Cell
  • 自动布局之autoresizingMask使用详解(StoryboardCode)
  • JSPatch技术文档
  • IOS屏蔽输出日志
  • android各种资源下载
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • Django 博客开发教程 8 - 博客文章详情页
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • JAVA SE 6 GC调优笔记
  • jdbc就是这么简单
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • Python学习之路13-记分
  • vue--为什么data属性必须是一个函数
  • 机器学习 vs. 深度学习
  • 如何选择开源的机器学习框架?
  • 入门级的git使用指北
  • 使用Gradle第一次构建Java程序
  • 使用putty远程连接linux
  • 详解移动APP与web APP的区别
  • 学习Vue.js的五个小例子
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • ​香农与信息论三大定律
  • #14vue3生成表单并跳转到外部地址的方式
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • (2.2w字)前端单元测试之Jest详解篇
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (ibm)Java 语言的 XPath API
  • (分类)KNN算法- 参数调优
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (数据结构)顺序表的定义
  • (万字长文)Spring的核心知识尽揽其中
  • (转)visual stdio 书签功能介绍
  • (转)winform之ListView
  • (转)我也是一只IT小小鸟
  • ***通过什么方式***网吧
  • ... 是什么 ?... 有什么用处?
  • .gitignore文件_Git:.gitignore
  • .htaccess配置常用技巧
  • .net core 客户端缓存、服务器端响应缓存、服务器内存缓存
  • .NET Core中的去虚
  • .NET中GET与SET的用法
  • .vimrc php,修改home目录下的.vimrc文件,vim配置php高亮显示
  • /3GB和/USERVA开关
  • @Valid和@NotNull字段校验使用
  • [ IO.File ] FileSystemWatcher