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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值