iOS 中对IPv6的适配

来源:互联网 发布:linux用户加入组 编辑:程序博客网 时间:2024/05/17 01:43

在ios应用的开发中,如果项目中网络层用的是SOCKET 底层 的api。需要在工程做 兼容ipv4和ipv6网络环境的处理。

解决方案:

    服务器地址配置为域名,通过解析域名的方式,得到 该域名映射的ip地址,再通过这个ip地址,去进行网络通信。

    就是将服务器的地址,通过域名解析函数,解析为相应网络环境的ip地址。再通过这个ip地址,去和服务器通信。

    如果客户端是在ipv6网络环境下,解析服务器地址的时候,会得到一个ipv6的地址。在客户端根据这个服务器的ipv6地址,建立客户端ipv6     网络环境下的 socket 通信;

    如果客户端是在ipv4网络环境下,解析服务器地址的时候,会得到一个ipv4的地址。在客户端根据这个服务器的ipv4地址,建立客户端ipv4 网络环境下的 socket 通信;

    因为ipv4和ipv6网络环境下,有很多api不同,因此,不同网络,要做不同判断。

    实践证明,如果服务器不是配置的域名,而是配置的Ipv4的一个地址,不会 影响 我们程序的正常解析。

    我们可以通过解析出来的 addrinfo结构体中 协议族(AF_INET、AF_INET6),知道当前客户端网络环境是Ipv4还是ipv6

核心代码:

1.解析服务器的域名(或服务器的 ipv4地址);

2.得到和客户端这边网络环境匹配的ip地址(如果客户端网络环境是ipv4,解析得到的是一个ipv4的地址;如果客户端网络环境是ipv6,解析得到的是一个ipv6的地址)

3.调用相应 网络环境下的 socket连接方法,实现socket的连接。

int NS_Socket::Connect(const char *Host, unsigned short Port)

{  

    struct addrinfo * result;

    struct addrinfo * res;

  

    int error;

   

    error = getaddrinfo(Host, NULL, NULL, &result);

    if(error != 0) {

        NSLog(@"error in getaddrinfo:%d", error);

        return NS_SOCKET_ERROR_HOST_NOTFOUND;

    }

    for(res = result; res!=NULL; res = res->ai_next) {

        char hostname[1025] = "";

        error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, 1025, NULL, 0, 0);

        NSLog(@"hostname=%s",hostname);

        

        if(error != 0) {

            NSLog(@"error in getnameifno: %s", gai_strerror(error));

            continue;

        }

        else {

            switch (res->ai_addr->sa_family)

            {

                    case AF_INET6:

                {

                

                    if(subConnectServerIPV6(hostname ,Port)==0)

                    {

                    NSLog(@"6连接成功");

                        

                    freeaddrinfo(result);


                    return 0;

                        

                    }else{

                        

                        return subConnectServerIPV6(hostname ,Port);

                        

                    }

                    

                }

                    break;

                    case AF_INET:

                {

                    if(subConnectServerIPV4(hostname ,Port)==0)

                    {

                        NSLog(@"4连接成功");

                        

                        freeaddrinfo(result);

                        return 0;


                    }else

                    {

                        return subConnectServerIPV4(hostname ,Port);


                    }


                }

                    break;

                    default:

                    break;           

            }


      

            NSLog(@"hostname: %s ", hostname);

        }

    }

    

    return NS_SOCKET_ERROR_CONNECT;

}

本地搭建IPv6测试环境

首先需要的就是一台用非Wi-Fi的方式上网的Mac电脑。其本质就是用Mac做一个热点,然后用iPhone连接这个Wi-Fi,区别是这次我们产生的是一个本地的IPv6 DNS64/NAT64网络,这项功能是OS X 10.11新加的。和我们以前开启热点方式不一样的地方在于,我们在“System Preferences”界面选中“Sharing”的同时,要按住“Option”键。

之后在“Sharing”界面中,我们会看到和之前不一样的地方,就是红框所标的地方,多了一个叫“Create NAT64 Network”的选框,选中它。之后就是按照正常的创建热点的流程走完就行了。




0 0
原创粉丝点击