【iOS】IPv6網路相容問題總結
阿新 • • 發佈:2019-02-03
新增標頭檔案
#include <sys/socket.h>
#include <netdb.h>
#include <err.h>
#include <net/if.h>
#define OUTSTR_SIZE 128
#define IOS_CELLULAR @"pdp_ip0"
#define IOS_WIFI @"en0"
在IPv6網路環境下,IPv4地址轉IPv6地址
** 將IPv4地址轉換為IPv6 注意:IPv6網路環境下獲取的IPv4地址才能轉換成IPv6地址 @param host 主機IP地址 @return ipv6|address/ipv4|address */ const char* transferToIPv6(const char* host) { if ((host == NULL) || (strlen(host) == 0)) { return copyString("ERROR_HOSTNULL"); } struct addrinfo hints, *res, *res0; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_DEFAULT; hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; //轉換函式,返回addrinfo的結構 int error = getaddrinfo(host, "http", &hints, &res0); if (error != 0) { printf("getaddrinfo: %s\n", gai_strerror(error)); return copyString("ERROR_GETADDR"); } char outstr[OUTSTR_SIZE]; memset(outstr, 0, sizeof(char)*OUTSTR_SIZE ); struct sockaddr_in6* addr6; struct sockaddr_in* addr; const char* solvedaddr; char ipbuf[32]; for(res = res0; res; res = res->ai_next) { if (res->ai_family == AF_INET6) { addr6 = (struct sockaddr_in6*)res->ai_addr; solvedaddr = inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, sizeof(ipbuf)); strcat(outstr, "ipv6|"); strcat(outstr, solvedaddr); }else { addr = (struct sockaddr_in*)res->ai_addr; solvedaddr = inet_ntop(AF_INET, &addr->sin_addr, ipbuf, sizeof(ipbuf)); strcat(outstr, "ipv4|"); strcat(outstr, solvedaddr); } } NSLog(@"當前裝置IP: %s", outstr); freeaddrinfo(res0); return copyString(outstr); }
獲取當前裝置連線WiFi時的IP地址
enum NetworkType { CELLULAR, WIFI }; /** 獲取當前裝置的IP地址 @return IP地址 */ const char* getDeviceIP(enum NetworkType type) { struct ifaddrs *res, *res0; int error = getifaddrs(&res0); if (error != 0) { return copyString("ERROR_GETADDR"); } struct sockaddr_in6* addr6; struct sockaddr_in* addr; const char* solvedaddr; char ipbuf[32]; NSString *address = @"0.0.0.0"; NSString *neworkType = (type == WIFI) ? IOS_WIFI:IOS_CELLULAR; for(res = res0; res; res = res->ifa_next) { if (!(res->ifa_flags& IFF_UP) &&!(res->ifa_flags & IFF_RUNNING)) { continue; } NSString *ifa_name = [NSString stringWithUTF8String:res->ifa_name]; if (ifa_name && ![ifa_name isEqualToString:neworkType]) { continue; } if (res->ifa_addr->sa_family == AF_INET6) { addr6 = (struct sockaddr_in6*)res->ifa_addr; solvedaddr = inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, sizeof(ipbuf)); address = [NSString stringWithFormat:@"ipv6|%s", solvedaddr]; }else { addr = (struct sockaddr_in*)res->ifa_addr; solvedaddr = inet_ntop(AF_INET, &addr->sin_addr, ipbuf, sizeof(ipbuf)); address = [NSString stringWithFormat:@"ipv4|%s", solvedaddr]; } } NSLog(@"當前裝置IP: %@", address); freeifaddrs(res0); return copyString([address UTF8String]); }