苹果公司6月1日后发布的应用必须支持IPv6-Only网络的解决办法(底层socket连接的IPv6支持方案)
来源:互联网 发布:hr绿宝瓶面霜 知乎 编辑:程序博客网 时间:2024/06/01 08:12
苹果在去年的WWDC2015中宣布在今年的6月1日之后发布的应用必须支持IPv6-Only的网络环境。
苹果官方给出的解决方法是:
IP address literals embedded in protocols. Many communications protocols, such as Session Initiation Protocol (SIP), File Transfer Protocol (FTP), WebSockets, and Peer-to-Peer Protocol (P2PP), include IP address literals in protocol messages. For example, the
FTP
parameter commandsDATA PORT
andPASSIVE
exchange information that includes IP address literals. Similarly, IP address literals may appear in the values of SIP header fields, such asTo
,From
,Contact
,Record-Route
, andVia
. See Use High-Level Networking Frameworks and Don’t Use IP Address Literals.IP address literals embedded in configuration files. Configuration files often include IP address literals. See Don’t Use IP Address Literals.
Network preflighting. Many apps attempt to proactively check for an Internet connection or an active Wi-Fi connection by passing IP address literals to network reachability APIs. See Connect Without Preflight.
Using low-level networking APIs. Some apps work directly with sockets and other raw network APIs such as
gethostbyname
,gethostbyname2
, andinet_aton
. These APIs are prone to misuse or they only support IPv4—for example, resolving hostnames for theAF_INET
address family, rather than theAF_UNSPEC
address family. See Use High-Level Networking Frameworks.Using small address family storage containers. Some apps and networking libraries use address storage containers—such as
uint32_t
,in_addr
, andsockaddr_in
—that are 32 bits or smaller. See Use Appropriately Sized Storage Containers. [1]
而在我们的工程中需要使用底层C++的socket建立长连接来进行信息交互,因此我们需要对我们的工程中的socket连接进行IPv6 Only网络下的适配工作。
首先介绍下IPv6:
从很久远的计算机网络课堂中我们得知IPv6是为了弥补IPv4网络环境下地址数量有限而诞生的容量更大的网络地址协议。目前在中国,当我们用网络设备连接上有线网络、大部分无线网络(部分无线路由局域网内使用IPv6)、4G、3G等网络时,设备被分配的地址均为IPv4地址(教育网部分使用IPv6),但是随着不同国家不同的运营商和企业逐渐部署IPv6 DNS64/NAT64网络之后,设备被分配的地址会变成IPv6的地址,而这些网络就是所谓的IPV6-Only网络,并且仍然可以通过此网络去获取IPV4地址提供的内容 [3]。
他们访问IPv4地址时的过程是这样的:
客户端向服务器端请求域名解析,首先通过DNS64 Server查询IPv6的地址,如果查询不到,再向DNS Server查询IPv4地址,通过DNS64 Server将查询到的IPv4地址合成为一个IPv6的地址,最终将一个IPv6的地址返回给客户端 [3]。如下图所示:
而在我们的底层socket连接中,并不支持使用域名来通过DNS Server来兼容IPv4和IPv6网络来建立连接,而需要我们以P2P的方式直接使用服务器的IP Address来直接建立连接。那么我们需要在IPv6-Only的网络下手动把IPv4的地址合成为IPv6的地址,来访问服务器。此外对于服务端我们需要的让服务器能够兼容IPv4和IPv6的客服端发来的连接请求,我不太清楚服务端的代码,具体方法请参考参考文献[2]。
在代码中我们建立socket连接的地方,我们需要手动来判断当前网络来生成对应IP格式。这里在iOS 9.2版本之后,苹果宣布 'getaddrinfo' 方法将可以支持按照当前网络环境得到IPv4或者IPv6的地址。这需要我们载入"#include <netdb.h>"和"#include <arpa/inet.h>"。具体的代码如下:
// clear previous socketsif(mySocket>=0){ close(mySocket); mySocket=-1;}struct addrinfo hints, *res, *ressave;bzero(&hints, sizeof(hints));hints.ai_family = PF_UNSPEC;hints.ai_socktype = SOCK_STREAM;char szPort[10]={0};sprintf(szPort, "%d",nPort);int ret;// get IPv4 or IPv6 address according to the App running network (IPv4 or IPv6)if (0 != (ret = getaddrinfo(szIP, szPort, &hints, &res))){ return -1;}// set the port of IP address, because sometime the port value will be set to '0'if (res->ai_family == AF_INET6) {{ sockaddr_in6 *paddrinfo=(sockaddr_in6 *)res->ai_addr; paddrinfo->sin6_port = htons(nPort);} else if (res->ai_family == AF_INET) { sockaddr_in6 *paddrinfo=(sockaddr_in *)res->ai_addr; paddrinfo->sin6_port = htons(nPort);}ressave = res;while (NULL != res){ //init socket if (-1 == (mySocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol))) { res = res->ai_next; continue; } //connect to the server if (-1 == connect(mySocket, res->ai_addr, res->ai_addrlen)) { close(mySocket); mySocket=-1; res = res->ai_next; continue; } break;}freeaddrinfo(ressave);建立完socket连接后,就可以按照原先的网络进行正常的发送/接收数据了。
相关参考文献:
1.Supporting IPv6 DNS64/NAT64 Networks
2.Application Aspects of IPv6 Transition
3.iOS应用支持IPV6,就那点事儿
4.针对苹果最新审核要求为应用兼容IPv6
5.NAT64与DNS64基本原理概述
- 苹果公司6月1日后发布的应用必须支持IPv6-Only网络的解决办法(底层socket连接的IPv6支持方案)
- 苹果:6月1日后所有应用必须支持IPv6-only网络
- 苹果App Store新规:6月1日后所有应用必须支持IPv6-only网络
- 苹果:所有应用必须支持IPv6-only网络
- iOS 应用完全支持 IPv6-ONLY 网络
- 关于IOS必须支持ipv6网络的爬坑经历
- ipv6 自从6月1号开始Appstore的审核需要支持ipv6
- 关于苹果审核,应用需支持IPV6的解决办法
- Unity ipv6的支持
- ipv6的兼容性支持
- Socket Programming下IPv6的支持
- C++创建支持IPv4/IPv6的Socket
- Swift - 如何让应用支持IPv6-only网络(附:搭建IPv6测试环境)
- iOS APP 支持IPv6-only的注意事项及兼容性考虑
- iOS APP 支持IPv6-only的注意事项及兼容性考虑
- iOS 应用如何完全支持 IPv6-ONLY 网络?
- 升级支持ipv4/ipv6后的Socket处理(cocos2dx项目苹果审核支持ipv6处理二)
- 阿里云服务器如何设置IPV6通过appstore的审核(拒绝是没有支持ipv6 only)
- 在浏览器中输入www.baidu.com后执行的全部过程
- Acdream 1214 Nice Patterns Strike Back (矩阵乘法 + 状态压缩)
- iOS_高效开发之道
- 初识Swift
- iOS开发:==、isEqual与isEqualToString判断是否相等
- 苹果公司6月1日后发布的应用必须支持IPv6-Only网络的解决办法(底层socket连接的IPv6支持方案)
- Halcon MFC混合编程-图像显示随鼠标滚动放大缩小
- jQuery初用 注册
- 实用小工具:电脑插入U盘后自动打开文件夹
- 使用boost::shared_ptr做为线程的参数
- iOS 应用将适应新的的IPv6-only网络 -解决方案
- 音乐源码重新上传了,请童鞋们自行下载
- CM系统刷机至真机
- YUV fullrange