首先别错误理解以为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. Bottle源码阅读笔记(一):WSGI

    前言 Bottle是一个Python Web框架.整个框架只有一个文件,不到4k行的代码,没有Python标准库以外的依赖,却包含了路由.模板和插件等Web框架常用功能.通过阅读Bottle源码来了解 ...

  2. Selenium基础知识

    本人博客文章网址:https://www.peretang.com/basic-knowledge-of-selenium/ 什么是Selenium Selenium是一个自动化测试工具 是一组不同的 ...

  3. CoreAnimation学习,学习总结,记录各种过程中遇到的坑

    1. CAAimation  的 duration = 0 的时候, 这个时候就相当于没有动画了. 2. CAKeyframeAnimation *rotateAnimation = [CAKeyfr ...

  4. Function.prototyoe.call.apply

    刚刚在一个群里看到有人问 Function.prototype.call.apply(obj, args) 如何理解,觉得挺有意思的.刚开始被惯性思维干扰了,一直都是 call 和 apply 分开用 ...

  5. Hibernate入门(四)

    一 Hibernate缓存 缓存是介于应用程序和数据库之间,对数据库中的数据复制一份到缓存中,其作用就是为了减少应用程序对数据库的访问,访问数据库时先从缓存中取,提高了程序的性能.Hibernate缓 ...

  6. Log4PHP 配置和使用

    Log4PHP2.3.0使用解释 1. 什么是Log4PHP Log4php它为apche组织维护项目,是Log4xx系列日志组件之一,log4j在JAVA中可算是大名鼎鼎的日志开发包.Log4PHP ...

  7. [USACO08NOV]奶牛混合起来Mixed Up Cows

    题目描述 Each of Farmer John's N (4 <= N <= 16) cows has a unique serial number S_i (1 <= S_i & ...

  8. ASP.NET Core配置Kestrel 网址Urls

    ASP.NET Core中如何配置Kestrel Urls呢,大家可能都知道使用UseUrls() 方法来配置. 今天给介绍全面的ASP.NET Core 配置 Urls,使用多种方式配置Urls.让 ...

  9. 【知识整理】这可能是最好的RxJava 2.x 入门教程(四)

    这可能是最好的RxJava 2.x入门教程系列专栏 文章链接: 这可能是最好的RxJava 2.x 入门教程(一) 这可能是最好的RxJava 2.x 入门教程(二) 这可能是最好的RxJava 2. ...

  10. mongodb入门笔记

    mongodb作为nosql中排名第一的数据库,近年来使用的人数越来越多,作为开发人员,非常有必要了解下mongodb数据库.下面就给大家介绍下mongodb数据库的基本知识,有不对的地方欢迎指正,Q ...