服务端改成了ipv6,ios客户端需要改什么

这是苹果的关于ipv6改造的官方文档

https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html#//apple_ref/doc/uid/TP40010220-CH213-SW1

 

简单整理了一下客户端的改动点。

 

 

A DNS64/NAT64 network is an IPv6-only network 

DNS64 / NAT64网络是仅IPv6的网络

 

If you’re writing a client-side app using high-level networking APIs such as NSURLSession and the CFNetwork frameworks and you connect by name, you should not need to change anything for your app to work with IPv6 addresses. If you aren’t connecting by name, you probably should be.

如果您使用诸如NSURLSession和和CFNetwork框架之类的高级网络API编写客户端应用程序,并且通过域名进行连接,则无需为应用程序使用IPv6地址而进行任何更改。如果您未按域名进行连接,则应该如此。

服务端改成了ipv6,ios客户端需要改什么_第1张图片



在这种类型的工作流中,客户端将DNS查询发送到DNS64服务器,该服务器从DNS服务器请求IPv6地址。找到IPv6地址后,它会立即传递回客户端。但是,当找不到IPv6地址时,DNS64服务器将改为请求IPv4地址。然后,DNS64服务器通过为IPv4地址添加前缀来合成IPv6地址,并将其传递回客户端。在这方面,客户端始终会收到一个支持IPv6的地址。

常见问题:

  1. 协议中嵌入的IP地址文字。许多通信协议,例如会话启动协议(SIP),文件传输协议(FTP),WebSocket和对等协议(P2PP),都在协议消息中包含IP地址文字。例如,FTP参数命令DATA PORT并PASSIVE交换包括IP地址文字的信息。类似地,IP地址文字可能出现在SIP报头字段的值,例如To,From,Contact,Record-Route,和Via。请使用高级网络框架和不使用IP地址文字。
  2. 嵌入配置文件中的IP地址文字。配置文件通常包含IP地址文字。请不使用IP地址文字。
  3. 网络预检。许多应用程序尝试通过将IP地址文字传递给网络可达性API来主动检查Internet连接或活动的Wi-Fi连接。请不进行预检的连接。
  4. 使用低级网络API。有些应用与插座等原始网络API,如直接工作gethostbyname,gethostbyname2和inet_aton。这些API容易被滥用,或者它们仅支持IPv4,例如,解析AF_INET地址族而不是AF_UNSPEC地址族的主机名。请使用高级网络框架。
  5. 使用小型地址系列存储容器。一些应用程序和网络库使用地址存储容器-如uint32_t,in_addr,和sockaddr_in-即都是32位或更小。请使用适当大小的存储容器。

 

使用高级网络框架

WebKit. 

Cocoa URL loading system.  NSURLSessionNSURLRequest, and NSURLConnection

CFNetwork. 打开主机的一对TCP套接字,请调用CFStreamCreatePairWithSocketToCFHost方法

不要使用IP地址

不要用如getaddrinfoSCNetworkReachabilityCreateWithName。而是使用高级网络框架和与地址无关的API版本(例如getaddrinfo和)getnameinfo。

无需测试连通性即可连接

如果必须检查网络可用性,请避免调用SCNetworkReachabilityCreateWithAddress方法。调用SCNetworkReachabilityCreateWithName方法。

使用适当大小的存储容器

使用sockaddr_storage足够大的地址存储容器(例如)来存储IPv6地址。

检查IPv6 DNS64 / NAT64不兼容的源代码

检查并消除特定于IPv4的API,例如:

inet_addr()
inet_aton()
inet_lnaof()
inet_makeaddr()
inet_netof()
inet_network()
inet_ntoa()
inet_ntoa_r()
bindresvport()
getipv4sourcefilter()
setipv4sourcefilter()
如果您的代码处理的是IPv4类型,请确保也处理了等效的IPv6。

IPv4

IPv6

AF_INET

AF_INET6

PF_INET

PF_INET6

struct in_addr

struct in_addr6

struct sockaddr_in

struct sockaddr_in6

kDNSServiceProtocol_IPv4

kDNSServiceProtocol_IPv6

 

如果实在没有域名

请使用getaddrinfo解析IPv4地址文字。如果当前网络接口不支持IPv4,但支持IPv6,NAT64和DNS64,则执行此任务将得到一个合成的IPv6地址。

如何使用解析IPv4文字getaddrinfo。假设您有一个以四个字节(例如{192, 0, 2, 1})存储在内存中的IPv4地址,此示例代码将其转换为字符串(例如"192.0.2.1"),用于getaddrinfo合成IPv6地址(例如struct sockaddr_in6包含IPv6地址"64:ff9b::192.0.2.1")并尝试连接到该IPv6地址。
#include 
#include 
#include 
#include 
 
    uint8_t ipv4[4] = {192, 0, 2, 1};
    struct addrinfo hints, *res, *res0;
    int error, s;
    const char *cause = NULL;
 
    char ipv4_str_buf[INET_ADDRSTRLEN] = { 0 };
    const char *ipv4_str = inet_ntop(AF_INET, &ipv4, ipv4_str_buf, sizeof(ipv4_str_buf));
 
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_DEFAULT;
    error = getaddrinfo(ipv4_str, "http", &hints, &res0);
    if (error) {
        errx(1, "%s", gai_strerror(error));
        /*NOTREACHED*/
    }
    s = -1;
    for (res = res0; res; res = res->ai_next) {
        s = socket(res->ai_family, res->ai_socktype,
                   res->ai_protocol);
        if (s < 0) {
            cause = "socket";
            continue;
        }
 
        if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
            cause = "connect";
            close(s);
            s = -1;
            continue;
        }
 
        break;  /* okay we got one */
    }
    if (s < 0) {
        err(1, "%s", cause);
        /*NOTREACHED*/
    }
    freeaddrinfo(res0);


注意:在iOS 9.2和OS X 10.11.2中,getaddrinfo增加了合成IPv6地址的能力。但是,利用它不会破坏与旧系统版本的兼容性。

 

 

 

 

 

 

你可能感兴趣的:(ios)