标签:
苹果官方出了新的规定,要求新上架的app都必须单独支持ipv6-only的网络。
搭建IPV6测试环境:http://blog.csdn.net/potato512/article/details/51680203
在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的连接。关键代码,已经用红色标识了。
1 // TODO:兼容ipv4和IPV6网络环境... 2 bool TcpClientSocket::ConnectServer(const char *pServerIP,unsigned short ServerPort) 3 { 4 struct addrinfo * result = NULL; 5 struct addrinfo * res = NULL; 6 int error; 7 CCLog("TcpClientSocket::function [%s] line [%d] ....传入的参数:pServerIP=%s, ServerPort=%d, ------ ", __FUNCTION__, __LINE__, pServerIP, ServerPort ); 8 9 error = getaddrinfo(pServerIP, NULL, NULL, &result); 10 if(error != 0) 11 { 12 // 域名解析失败,直接返回 ..... 13 CCLog("域名解析失败,直接返回 .....TcpClientSocket::function [%s] line [%d] error in pServerIP[%s], port[%d], getaddrinfo:%d, strErr=%s", __FUNCTION__, __LINE__, pServerIP, ServerPort, error, gai_strerror(error)); 14 return false; 15 } 16 17 for(res = result; res!=NULL; res = res->ai_next) 18 { 19 char hostname[1025] = ""; 20 error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, 1025, NULL, 0, 0); 21 if(error != 0) 22 { 23 CCLog("获取主机信息失败????:TcpClientSocket::function [%s] line [%d] error in pServerIP[%s], port[%d], getnameifno: %s", __FUNCTION__, __LINE__, pServerIP, ServerPort, gai_strerror(error)); 24 continue; 25 } 26 else 27 { 28 std::string ip = hostname; 29 switch (res->ai_addr->sa_family) 30 { 31 case AF_INET: 32 { 33 if(subConnectServerIPV4(ip.c_str(), ServerPort)) 34 { 35 // IPV4 连接成功 36 CCLog("TcpClientSocket::IPV4,连接成功了. IP:%s, port:%d", ip.c_str(), ServerPort); 37 freeaddrinfo(result); 38 return true; 39 } 40 else 41 { 42 CloseSocket(); 43 // IPV4 连接失败 44 CCLog("TcpClientSocket::IPV4,连接失败,继续查找... IP:%s, port:%d", ip.c_str(), ServerPort); 45 } 46 } 47 break; 48 49 case AF_INET6: 50 { 51 if(subConnectServerIPV6(ip.c_str(), ServerPort)) 52 { 53 // IPV6 连接成功 54 CCLog("TcpClientSocket::IPV6,连接成功了. IP:%s, port:%d", ip.c_str(), ServerPort); 55 freeaddrinfo(result); 56 return true; 57 } 58 else 59 { 60 CloseSocket(); 61 // IPV6 连接失败 62 CCLog("TcpClientSocket::IPV6,连接失败,继续查找... IP:%s, port:%d", ip.c_str(), ServerPort); 63 } 64 } 65 break; 66 67 default: 68 CCLog("TcpClientSocket::switch (res->ai_addr->sa_family)======= 这是一条异常的log "); 69 break; 70 }// end switch 71 }//end else 72 }// end for 73 74 freeaddrinfo(result); 75 CCLog("TcpClientSocket::Ipv6,Ipv4连接均失败!!! function [%s] line [%d] pServerIP:%s, port:%d ", __FUNCTION__, __LINE__, pServerIP, ServerPort); 76 return false; 77 } 78 79 bool TcpClientSocket::subConnectServerIPV4(const char *pServerIP, unsigned short ServerPort) 80 { 81 CCLog("TcpClientSocket::function [%s] line [%d] ip [%s] port [%d]", __FUNCTION__, __LINE__, pServerIP, ServerPort); 82 struct sockaddr_in addrServer; 83 int tempSocket = -1; 84 85 memset(&addrServer, 0, sizeof(addrServer)); 86 addrServer.sin_family = AF_INET; 87 addrServer.sin_port = htons(ServerPort); 88 addrServer.sin_addr.s_addr = inet_addr(pServerIP); 89 90 if((tempSocket = socket(AF_INET,SOCK_STREAM,0)) < 0) 91 { 92
93 CCLOG("TcpClientSocket::function [%s] line [%d]", __FUNCTION__, __LINE__); 94 return false; 95 } 96 97 if(connect(tempSocket, (struct sockaddr*)&addrServer, sizeof(addrServer)) < 0) 98 { 99 CCLOG("TcpClientSocket::function [%s] line [%d]", __FUNCTION__, __LINE__); 100 return false; 101 } 102 return true; 103 } 104 105 bool TcpClientSocket::subConnectServerIPV6(const char *pServerIP, unsigned short ServerPort) 106 { 107 CCLog("TcpClientSocket::function [%s] line [%d]", __FUNCTION__, __LINE__); 108 struct sockaddr_in6 addrServer; 109 int tempSocket = -1; 110 111 memset(&addrServer, 0, sizeof(addrServer)); 112 addrServer.sin6_family = AF_INET6; 113 addrServer.sin6_port = htons(ServerPort); 114 inet_pton(AF_INET6, pServerIP, &addrServer.sin6_addr); 115 if((tempSocket = socket(AF_INET6,SOCK_STREAM,0)) < 0) 116 { 117 state=NETWORK_STATE_FAILED; 118 CCLog("TcpClientSocket::%s socket err... line [%d]", __FUNCTION__, __LINE__); 119 return false; 120 } 121 122 if(connect(tempSocket, (struct sockaddr*)&addrServer, sizeof(addrServer)) < 0) 123 { 124 CCLog("TcpClientSocket::%s connect err... line [%d]", __FUNCTION__, __LINE__); 125
126 return false; 127 } 128 return true; 129 }
cocos2d-x工程中,需要升级curl版本。
去cocos2d-x官网下载最新的包(目前最新版本是3.10),找到 curl文件夹,将里面的 文件,替换到你工程对应的curl目录下面。
还需要 替换 libraries文件夹下面的若干 lib库。再在你的工程里面,重新 添加这些库。重新编译工程。
参考连接:
http://www.cnblogs.com/yans/p/5558178.html
标签:
原文地址:http://www.cnblogs.com/MasterOogway/p/5778408.html