首先别错误理解以为app 必须支持 ipv6 的服务端, 只需要支持 ipv6的客户端需要访问 ipv4 的服务端。

目前需要经过  NAT64 转换就能达到目的,客户端只需要支持该转换就能实现, 在OS X的系统上是的wifi 共享有支持 NAT64转换,提供了这个功能就方便了我们可以使用手机链接 OS X上的热点模拟这个测试环境。

我们代码上所需要完成​的事情:

1.客户端需要链接的ip地址(ipv4) 通过转换。

 getaddrinfo​ //方法可以转换为 ipv6 的地址。

 ​struct addrinfo hints, *res, *res0;

 memset(&hints, , sizeof(hints));

 hints.ai_family = PF_UNSPEC;

 hints.ai_socktype = SOCK_STREAM;

 #if (PLATFORM == PLATFORM_WIN32)

 hints.ai_flags = AI_PASSIVE;

 #else

 hints.ai_flags = AI_DEFAULT;
18 #endif int error = getaddrinfo(pServerIP, "http", &hints, &res0);

2.经过转换后我们可以判断 ai_family 兼容 非NAT64 转换的网络环境与 NAT64转换的网络环境 下进行 socket的链接:

 struct sockaddr_in addr_in;

 struct sockaddr_in6 addr_in6;

 int connect_ret;

 for (res = res0; res; res = res->ai_next) {

      connect_ret = -;

       tempSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

      if (tempSocket < ) {

              continue;

        }

       if(AF_INET == res->ai_family){

            addr_in = *((struct sockaddr_in *)res->ai_addr);

            addr_in.sin_port = htons(ServerPort);

            connect_ret = connect(tempSocket, (struct sockaddr *)&addr_in, res-      >ai_addrlen);

         }else if(AF_INET6 == res->ai_family){

                 addr_in6  = *((struct sockaddr_in6 *)res->ai_addr);

                 addr_in6.sin6_port = htons(ServerPort);

                 connect_ret = connect(tempSocket, (struct sockaddr *)&addr_in6, res->ai_addrlen);

         }

        if (connect_ret < ) {

             cause = "connect";

 #if (PLATFORM == PLATFORM_WIN32)

             closesocket(tempSocket);

 #else

             close(tempSocket);

 #endif

             tempSocket = -;

             continue;

       }

       break; 

 }

OK,这样就支持 ipv6 对 ipv4 的网络 而且兼容 普通 ipv4 对 ipv4 的网络。​

上面是没有考虑链接时候客户端会进入卡死状态直到链接成功, 因为加上去代码会复杂点,为了好看就没有加上, 真实项目中需要改为非阻塞模式, 通过select 来判断是否connect成功。

下面是加上非阻塞模式:

     int tempSocket = -;
struct addrinfo hints, *res, *res0;
int error;
const char *cause = NULL; memset(&hints, , sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(pServerIP, NULL, &hints, &res0);
if (error) {
CCLOG("getaddrinfo error:%d", error);
return false;
} struct sockaddr_in addr_in;
struct sockaddr_in6 addr_in6;
for (res = res0; res; res = res->ai_next) {
tempSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (tempSocket < ) {
cause = "socket";
continue;
} #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
// 设定 非阻塞
unsigned long tmepOption = ; //0:阻塞
ioctlsocket(tempSocket, FIONBIO, &tmepOption);
#else
// 设定 非阻塞
int flag = fcntl(tempSocket, F_GETFL, );
fcntl(tempSocket, F_SETFL, flag | O_NONBLOCK);
#endif if(AF_INET == res->ai_family){
addr_in = *((struct sockaddr_in *)res->ai_addr);
addr_in.sin_port = htons(ServerPort);
connect(tempSocket, (struct sockaddr *)&addr_in, res->ai_addrlen);
}else if(AF_INET6 == res->ai_family){
addr_in6 = *((struct sockaddr_in6 *)res->ai_addr);
addr_in6.sin6_port = htons(ServerPort);
connect(tempSocket, (struct sockaddr *)&addr_in6, res->ai_addrlen);
} fd_set fset;
FD_ZERO(&fset);
FD_SET(tempSocket, &fset); timeval timeout;
timeout.tv_sec = ; // 1.5秒超时, 上层逻辑会尝试3次 >> 1.5 * 3
timeout.tv_usec = ;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
socklen_t len = sizeof(error);
#else
int len = sizeof(error);
#endif
if( select(tempSocket+, NULL, &fset, NULL, &timeout) > )
{
if (FD_ISSET(tempSocket, &fset))
{
getsockopt(tempSocket, SOL_SOCKET, SO_ERROR, (char *)&error, &len);
if(error == ){
break;
}
}
} #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
closesocket(tempSocket);
#else
close(tempSocket);
#endif
tempSocket = -; } if (tempSocket < ) {
CCLOG("connect server error:%d", tempSocket);
goto RETURN_FALSE;
} if(false){
RETURN_FALSE:
freeaddrinfo(res0);
return false;
}

支持苹果IPV6 ONLY 的socket 修改方法的更多相关文章

  1. 服务器配置ssl证书支持苹果ATS方法

    服务器配置ssl证书支持苹果ATS方法 发布日期:2016-12-14 苹果安全工程&架构部门主管Ivan Kristic表示ATS将在今年底成为App Sotre app的必要条件,这将大幅 ...

  2. Linux配置支持高并发TCP连接(socket最大连接数)

    Linux配置支持高并发TCP连接(socket最大连接数) Linux配置支持高并发TCP连接(socket最大连接数)及优化内核参数 2011-08-09 15:20:58|  分类:LNMP&a ...

  3. as关键词还有另外一个用途,那就是修改 方法 的访问控制

    PHP是单继承的语言,在PHP 5.4 Traits出现之前,PHP的类无法同时从两个基类继承属性或方法.php的Traits和Go语言的组合功能类似,通过在类中使用use关键字声明要组合的Trait ...

  4. Oracle 11g RAC环境下Private IP修改方法及异常处理

    Oracle 11g RAC环境下Private IP修改方法及异常处理 Oracle 11g RAC环境下Private IP修改方法及异常处理 一. 修改方法 1. 确认所有节点CRS服务以启动 ...

  5. dedecms 使noflag参数及其过滤多个属性的修改方法

    noflag='h' 是代表不包含头条属性的意思,其中flag就是属性, 自定义属性值:头条[h]推荐[c]图片[p]幻灯[f]滚动[s]跳转[j]图文[a]加粗[b]. noflag过滤多个属性的修 ...

  6. 使用cocoapods的两个大坑的修改方法

    1.报错内容: [!] The dependency `ReactiveCocoa (= 2.1.8)` is not used in any concrete target. The depende ...

  7. Linux网卡调优篇-禁用ipv6与优化socket缓冲区大小

    Linux网卡调优篇-禁用ipv6与优化socket缓冲区大小 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   一般在内网环境中,我们几乎是用不到IPV6,因此我们没有必要把多不 ...

  8. 迅为4412开发板QtE系统源码-屏幕横竖屏切换修改方法

    迅为4412开发板QtE系统源码-屏幕横竖屏切换修改方法 详情了解:http://topeetboard.com 更多了解:https://arm-board.taobao.com/ 用户在开发板上运 ...

  9. Socket.BeginConnect 方法

    Socket.BeginConnect 方法 (IPAddress, Int32, AsyncCallback, Object) 开始一个对远程主机连接的异步请求. 主机由 IPAddress 和端口 ...

随机推荐

  1. scrapy跟pyspider的杂谈

    最近有一个私人项目要搞,可能最近的博客都会变成爬虫跟数据分析类的了.既然是爬虫,第一反应想到的就是鼎鼎大名的scrapy了,其次想到的pyspider,最后想到的就是自己写. scrapy是封装了tw ...

  2. (原创)用Java实现链表结构对象:单向无环链表

    转载请注明本文出处:http://www.cnblogs.com/Starshot/p/6918569.html 链表的结构是由一个一个节点组成的,所谓链,就是每个节点的头尾连在一起.而单向链表就是: ...

  3. WebSocket+MSE——HTML5 直播技术解析

    作者 | 刘博(又拍云多媒体开发工程师) 当前为了满足比较火热的移动 Web 端直播需求,一系列的 HTML5 直播技术迅速的发展起来. 常见的可用于 HTML5 的直播技术有 HLS.WebSock ...

  4. Java将头像图片保存到MySQL数据库

    在做头像上传的过程中通常是将图片保存到数据库中,这里简单介绍一中将图片保存到数据库的方法: jsp代码: <div> <input class="avatar-input& ...

  5. Spring+SpringMVC+MyBatis深入学习及搭建(九)——MyBatis和Spring整合

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6964162.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(八)--My ...

  6. 关于JS跨域问题的解决

    这里不提供什么高深的代码了,只说明一个解决跨域问题的方法,个人觉得这个方法是最方便也是最有效的. 那就是一用不同源的JS,虽然JS不允许不同源的访问,但是可以引用不同源的JS,用这样的方法我们可以引用 ...

  7. ActiveMQ 和消息简介

    Apache ActiveMQ 是远程系统间进行通信的消息代理,实现了 JMS(Java Message Service,Java 消息服务).尽管 ActiveMQ 是使用 Java 写的,但是其提 ...

  8. Hibernate 案例

    搭建一个Hibernate环境,开发步骤: 1. 下载源码 版本:hibernate-distribution-3.6.0.Final 2. 引入jar文件          hibernate3.j ...

  9. Bash shell执行命令的优先级

    1.别名2.关键字:if.function.while .until等3.函数4.内置命令5.可执行程序或脚本 别关函内可 =-=-=-=-=Powered by Blogilo

  10. IPhone开发“此证书是由未知颁发机构签名”解决办法

    有一种情况是你删除了钥匙串中的系统文件,只要重新下载,并双击(会自动添加到钥匙串中)就ok了. 从浏览器中直接敲入下载地址:http://developer.apple.com/certificati ...