前言:

苹果官方出了新的规定,要求新上架的app都必须单独支持ipv6-only的网络。

准备工作:

搭建IPV6测试环境:http://blog.csdn.net/potato512/article/details/51680203  (注意:第2步,按住 Option 键,打开 共享,才能看到NAT64选项!)

问题的提出:

在ios应用的开发中,如果项目中网络层用的是SOCKET 底层 的api。需要在工程做 兼容ipv4和ipv6网络环境的处理。

解决方案:

服务器地址配置为域名,通过解析域名的方式,得到 该域名映射的ip地址,再通过这个ip地址,去进行网络通信。

我们主要做什么?

将服务器的地址,通过域名解析函数,解析为相应网络环境的ip地址。再通过这个ip地址,去和服务器通信。

如果客户端是在ipv6网络环境下,解析服务器地址的时候,会得到一个ipv6的地址。在客户端根据这个服务器的ipv6地址,建立客户端ipv6 网络环境下的 socket 通信;

如果客户端是在ipv4网络环境下,解析服务器地址的时候,会得到一个ipv4的地址。在客户端根据这个服务器的ipv4地址,建立客户端ipv4 网络环境下的 socket 通信;

因为ipv4和ipv6网络环境下,有很多api不同,因此,不同网络,要做不同判断。

实践证明,如果服务器不是配置的域名,而是配置的Ipv4的一个地址,不会 影响 我们程序的正常解析。

我们可以通过解析出来的 addrinfo结构体中 协议族(AF_INET、AF_INET6),知道当前客户端网络环境是Ipv4还是ipv6。

网络通信部分关键代码:

1.解析服务器的域名(或服务器的 ipv4地址);

2.得到和客户端这边网络环境匹配的ip地址(如果客户端网络环境是ipv4,解析得到的是一个ipv4的地址;如果客户端网络环境是ipv6,解析得到的是一个ipv6的地址)

3.调用相应 网络环境下的 socket连接方法,实现socket的连接。关键代码,已经用红色标识了。

  1. // TODO:兼容ipv4和IPV6网络环境...
  2. bool TcpClientSocket::ConnectServer(const char *pServerIP,unsigned short ServerPort)
  3. {
  4. struct addrinfo * result = NULL;
  5. struct addrinfo * res = NULL;
  6. int error;
  7. CCLog("TcpClientSocket::function [%s] line [%d] ....传入的参数:pServerIP=%s, ServerPort=%d, ------ ", __FUNCTION__, __LINE__, pServerIP, ServerPort );
  8.  
  9. error = getaddrinfo(pServerIP, NULL, NULL, &result);
  10. if(error != )
  11. {
  12. // 域名解析失败,直接返回 .....
  13. CCLog("域名解析失败,直接返回 .....TcpClientSocket::function [%s] line [%d] error in pServerIP[%s], port[%d], getaddrinfo:%d, strErr=%s", __FUNCTION__, __LINE__, pServerIP, ServerPort, error, gai_strerror(error));
  14. return false;
  15. }
  16.  
  17. for(res = result; res!=NULL; res = res->ai_next)
  18. {
  19. char hostname[1025] = "";
  20. error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, 1025, NULL, 0, 0);
  21. if(error != )
  22. {
  23. CCLog("获取主机信息失败????:TcpClientSocket::function [%s] line [%d] error in pServerIP[%s], port[%d], getnameifno: %s", __FUNCTION__, __LINE__, pServerIP, ServerPort, gai_strerror(error));
  24. continue;
  25. }
  26. else
  27. {
  28. std::string ip = hostname;
  29. switch (res->ai_addr->sa_family)
  30. {
  31. case AF_INET:
  32. {
  33. if(subConnectServerIPV4(ip.c_str(), ServerPort))
  34. {
  35. // IPV4 连接成功
  36. CCLog("TcpClientSocket::IPV4,连接成功了. IP:%s, port:%d", ip.c_str(), ServerPort);
  37. freeaddrinfo(result);
  38. return true;
  39. }
  40. else
  41. {
  42. CloseSocket();
  43. // IPV4 连接失败
  44. CCLog("TcpClientSocket::IPV4,连接失败,继续查找... IP:%s, port:%d", ip.c_str(), ServerPort);
  45. }
  46. }
  47. break;
  48.  
  49. case AF_INET6:
  50. {
  51. if(subConnectServerIPV6(ip.c_str(), ServerPort))
  52. {
  53. // IPV6 连接成功
  54. CCLog("TcpClientSocket::IPV6,连接成功了. IP:%s, port:%d", ip.c_str(), ServerPort);
  55. freeaddrinfo(result);
  56. return true;
  57. }
  58. else
  59. {
  60. CloseSocket();
  61. // IPV6 连接失败
  62. CCLog("TcpClientSocket::IPV6,连接失败,继续查找... IP:%s, port:%d", ip.c_str(), ServerPort);
  63. }
  64. }
  65. break;
  66.  
  67. default:
  68. CCLog("TcpClientSocket::switch (res->ai_addr->sa_family)======= 这是一条异常的log ");
  69. break;
  70. }// end switch
  71. }//end else
  72. }// end for
  73.  
  74. freeaddrinfo(result);
  75. CCLog("TcpClientSocket::Ipv6,Ipv4连接均失败!!! function [%s] line [%d] pServerIP:%s, port:%d ", __FUNCTION__, __LINE__, pServerIP, ServerPort);
  76. return false;
  77. }
  78.  
  79. bool TcpClientSocket::subConnectServerIPV4(const char *pServerIP, unsigned short ServerPort)
  80. {
  81. CCLog("TcpClientSocket::function [%s] line [%d] ip [%s] port [%d]", __FUNCTION__, __LINE__, pServerIP, ServerPort);
  82. struct sockaddr_in addrServer;
  83. int tempSocket = -;
  84.  
  85. memset(&addrServer, , sizeof(addrServer));
  86. addrServer.sin_family = AF_INET;
  87. addrServer.sin_port = htons(ServerPort);
  88. addrServer.sin_addr.s_addr = inet_addr(pServerIP);

  89. if((tempSocket = socket(AF_INET,SOCK_STREAM,0)) < )
  90. {

  91. 93 CCLOG("TcpClientSocket::function [%s] line [%d]", __FUNCTION__, __LINE__);
  92. return false;
  93. }
  94.  
  95. if(connect(tempSocket, (struct sockaddr*)&addrServer, sizeof(addrServer)) < )
  96. {
  97. CCLOG("TcpClientSocket::function [%s] line [%d]", __FUNCTION__, __LINE__);
  98. return false;
  99. }
  100. return true;
  101. }
  102.  
  103. bool TcpClientSocket::subConnectServerIPV6(const char *pServerIP, unsigned short ServerPort)
  104. {
  105. CCLog("TcpClientSocket::function [%s] line [%d]", __FUNCTION__, __LINE__);
  106. struct sockaddr_in6 addrServer;
  107. int tempSocket = -;
  108.  
  109. memset(&addrServer, , sizeof(addrServer));
  110. addrServer.sin6_family = AF_INET6;
  111. addrServer.sin6_port = htons(ServerPort);
  112. inet_pton(AF_INET6, pServerIP, &addrServer.sin6_addr);
  113. if((tempSocket = socket(AF_INET6,SOCK_STREAM,0)) < )
  114. {
  115. state=NETWORK_STATE_FAILED;
  116. CCLog("TcpClientSocket::%s socket err... line [%d]", __FUNCTION__, __LINE__);
  117. return false;
  118. }
  119.  
  120. if(connect(tempSocket, (struct sockaddr*)&addrServer, sizeof(addrServer)) < )
  121. {
  122. CCLog("TcpClientSocket::%s connect err... line [%d]", __FUNCTION__, __LINE__);

  123. return false;
  124. }
  125. return true;
  126. }

补充:

cocos2d-x工程中,需要升级curl版本。

去cocos2d-x官网下载最新的包(目前最新版本是3.10),找到 curl文件夹,将里面的 文件,替换到你工程对应的curl目录下面。

还需要 替换 libraries文件夹下面的若干 lib库。再在你的工程里面,重新 添加这些库。重新编译工程。

参考连接:

http://www.cnblogs.com/yans/p/5558178.html

http://www.jianshu.com/p/8837739251ad?utm_campaign=hugo&utm_medium=reader_share&utm_content=note&utm_source=weixin-friends

http://blog.csdn.net/chenhanzhun/article/details/41944195

ios 兼容IPV4和IPV6网络通信的更多相关文章

  1. IPv6下网络编程socket, TCP和UDP例子,以及兼容IPV4和IPV6的类

    一.TCP socket ipv6与ipv4的区别 服务器端源代码如下: #include <stdio.h> #include <stdlib.h> #include < ...

  2. 提升iOS审核通过率之“IPv6兼容测试”

    作者:jingle 腾讯系统测试工程师 商业转载请联系腾讯WeTest授权,非商业转载请注明出处. 原文链接:http://wetest.qq.com/lab/view/285.html 一.背景 在 ...

  3. IPv4和IPv6的兼容问题

    一网络拓扑 Ipv6网络1 路由器A IPv4网络 路由器B IPv6网络2 二知识补充 [注]双协议栈主机(路由器A.B)通过域名解析器区分传过来的是IPv4还是IPv6 三处理技术 双协议栈 Ip ...

  4. IPv4和IPv6的差异;如何实现IPv4和IPv6双协议栈的通信

    1 IPv4和IPv6的差异 1.1 地址空间   IPv6 与 IPv4 比较最显著的一个改动就是使用 128 比特上的地址来代替了 32 比特长的 IPv4 地址. IPv6 中取消了广播地址, ...

  5. ipv4与ipv6 Inet4Address类和Inet6Address类

    在设置本地IP地址的时候,一些人会疑惑IPv4与IPv6的区别是什么?下面由学习啦小编为你分享ipv4与ipv6的区别的相关内容,希望对大家有所帮助. ipv4与ipv6的区别 在windows 7以 ...

  6. RFC2474 - Definition of the Differentiated Services Field (DS Field) in the IPv4 and IPv6 Headers的双语版

    RFC2474 - Definition of the Differentiated Services Field (DS Field) in the IPv4 and IPv6 Headers英文版 ...

  7. IPv4 与 IPv6的区别

    在介绍 IPv4 到 IPv6 区别之前,我们先来简单了解一下 IPv4 和 IPv6. IPv4 网际协议版本4(英语:Internet Protocol version 4,IPv4),又称互联网 ...

  8. IP地址(IPv4)/IPv6地址的正则表达式

    原地址:http://pfeishao.blog.163.com/blog/static/18162337020112113130453/ Pv4地址正则表达式:^((25[0-5]|2[0-4]\d ...

  9. ipv4、ipv6的socket同时监听“bind: Address already in use”的解决方法

    创建ipv4和ipv6的socket,同时监听某个端口的ipv4和ipv6报文,运行时bind函数执行失败,提示“bind: Address already in use”.原因:ipv6的socke ...

随机推荐

  1. [OC Foundation框架 - 7] NSArray的创建与遍历

    NSArray是不可变的,不能先创建再添加元素 NSArray可以放入任何OC对象,但不能放入基本数据类型.结构体.枚举等非OC对象 不能存储nil   A.常用方法1 创建 返回用量 是否含有某元素 ...

  2. [Objective-c 基础 - 3.4] protocol

    A.概念 1.用来声明方法(不能声明成员变量) 2.只要某个类遵守了这个协议,相当于拥有了协议中得所有方法的声明 3.属性 (1)@required:默认,要求实现,不实现就会发出警告 (2)@opt ...

  3. 起底多线程同步锁(iOS)

    iOS/MacOS为多线程.共享内存(变量)提供了多种的同步解决方案(即同步锁),对于这些方案的比较,大都讨论了锁的用法以及锁操作的开销,然后就开销表现排个序.春哥以为,最优方案的选用还是看应用场景, ...

  4. jQuery的遍历方法

    1.jQuery中的map使用方法 <!DOCTYPE html> <html> <head> <style>p { color:red; }</ ...

  5. 简单的谈一下.NET下的AOP

    AOP有着它优良的好处, 从一个层面上去关心一个问题, .NET对此有良好的支持.如果硬生生的看MSDN不理解里面的思想是有掉入深渊的感觉的. 为了理解AOP的机制, 我们从需求开始说起,实现AOP就 ...

  6. HDU 2013 蟠桃记

    蟠桃记 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  7. Windows下配置PHP支持LDAP扩展方法(wampserver)

    在网上搜了好多文章都不行呢,大都是没有开启扩展的问题,可是我的是开启的. 终于看到一篇文章,因为我用的是wampserver.下面是文章原话: 然后你发现上面的提示依旧,因为这是网上大多能查到的资料的 ...

  8. Codeforces Round #323 (Div. 1) B. Once Again... 暴力

    B. Once Again... Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/582/probl ...

  9. Ubuntu下配置 keepalived+nginx+tomcat 负载均衡

    本文力图阐述在 Ubuntu Server 环境下使用 Keepalived + Nginx + Tomcat 搭建高可用负载均衡环境的操作步骤和简约配置,这里不涉及性能调优.先说一下他们各自扮演的角 ...

  10. 【每日一摩斯】-【序列】-续-RAC and Sequences (853652.1)

    一个简单的sequence有什么可以说的呢?如果再这样认为就大错特错了... 也许以下几点高人们都很清楚,但至少对于我来说,之前是陌生的,或者说是忽略的. 1.CREATE SEQUENCE seq; ...