首先别错误理解以为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. JavaSE教程-01初识Java-思维导图

    图片看不清楚时: 1)可以将图片另存为图片,保存在本地来查看 2)右击在新标签中打开放大查看. 分解: 1.计算机基本概念的普及 硬件 cpu.内存.硬盘等 软件 系统级软件 Windows.Linu ...

  2. java基础(八章)

    一.        什么是数组及其作用? 定义:具有相同数据类型的一个集合 作用:存储连续的具有相同类型的数据 二.        java中如何声明和定义数组 l  声明和定义的语法: 数据类型[ ...

  3. Discuz插件开发之全站论坛目录结构注释

    基本上新版本的discuzX系列目录结构都差不多,刚好大神整理出来了,就拿来看吧. |-- /api        uc.php   UCenter通信文件        |-- /api/addon ...

  4. XtraBackup物理备份 阿里云的Mysql备份方案

    XtraBackup物理备份 Percona XtraBackup是世界上唯一的开源,免费的MySQL热备份软件,为InnoDB和XtraDB 数据库执行非阻塞备份.使用Percona XtraBac ...

  5. JavaScript设计模式_10_职责链模式

    职责链模式的定义是:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止.职责链模式的名字非常形象,一系列可能 ...

  6. mysql GROUP_CONCAT获取分组的前几名

    比如说要获取班级的前3名,oracle 可以用 over partition by 来做.mysql就可以用GROUP_CONCAT  + GROUP BY + substring_index实现. ...

  7. war包中少了class文件

    用eclipse的maven工具打包(执行mvn clean install  和   mvn package)后,再启动wildfly, war包应该会自动复制到wildfly的deployment ...

  8. 马踏棋盘算法递归+回溯法实现 C语言

    r为矩阵的行,c为矩阵的列 将结果输出到当前目录下的results.txt. 结果将给出:1.是否存在路径使马可以按要求走遍所有的方格: 2.解的总数: 3.程序执行的时间: #include< ...

  9. Itunes制作手机铃声,图文版

    一.下载歌曲,选择歌曲用itunes打开,打开出现下面界面 二.设置歌曲 右键点击歌曲,找到显示简介,点击选项,截取音乐,出现下图: 截取你喜欢的部分,点击确定 点击确定后,选中该歌曲,找到左上方 文 ...

  10. 【Android Developers Training】 106. 创建并检测地理围栏

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...