1. 程式人生 > >【iOS】IPv6網路相容問題總結

【iOS】IPv6網路相容問題總結

新增標頭檔案

#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]);
}