iOS 获取公网IP

创建了一个网络类,来读取外网IP
这是获取外网IP的类方法

// 获取外网IP地址
+ (nullable NSString *)externalIPAddress {
    @try {
        //检查是否连接网络
        // [self connectedToCellNetwork] 是否连接蜂窝网,这个方法单独写在下面了。
        // [self connectedToWiFi] 是否连接WiFi
        if (![self connectedToCellNetwork] && ![self connectedToWiFi]) {
            // 没有联网, return nil
            return nil;
        }
        
        // 从 icanhazip.com 网站获取IP地址
        NSError *error = nil;
   
        // 读取IP地址 https://icanhazip.com
        NSString *externalIP = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"https://icanhazip.com/"] encoding:NSUTF8StringEncoding error:&error];
        
        if (!error) {
            
            //去除 IP 地址的换行符和空格
            externalIP = [externalIP stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
            
            // 检查是否返回了IP地址
            if (externalIP == nil || externalIP.length <= 0) {
                // 错误或者未发现地址
                return nil;
            }
            
            // 返回IP地址
            return externalIP;
        } else {
             // 错误或者未发现地址
            return nil;
        }
    }
    @catch (NSException *exception) {
        // 错误或者未发现地址
        return nil;
    }
}

这里是判断是否连接蜂窝网或者WiFi的方法

// 是否连接 WiFi?
+ (BOOL)connectedToWiFi {
    //检查是否连接WiFi 
    // [self wiFiIPAddress] 获取WiFi地址 单独封装的方法
    NSString *wiFiAddress = [self wiFiIPAddress];
    // 检查WiFi地址字符串是否存在
    if (wiFiAddress == nil || wiFiAddress.length <= 0) {
        // 未发现
        return NO;
    } else {
        // WiFi 使用中
        returnYES;
    }
}

// 是否连接蜂窝网
+ (BOOL)connectedToCellNetwork {
    // 是否连接蜂窝网
    // [self cellIPAddress] 获取蜂窝网地址
    NSString *cellAddress = [self cellIPAddress];
    // 检查蜂窝网地址字符串是否存在
    if (cellAddress == nil || cellAddress.length <= 0) {
        // 未发现
        return NO;
    } else {
        // Cellular Network 使用中
        returnYES;
    }
}

后面的方法比较复杂了

1. 获取WiFi的IP地址

// 获取 WiFi IP 地址
+ (nullable NSString *)wiFiIPAddress {
    @try {
        // 初始化一个地址
        NSString *ipAddress;
        // 初始化结构体保存接口信息和临时地址
        struct ifaddrs *interfaces;
        struct ifaddrs *temp;
        // 记录成功失败状态
        int Status = 0;
        
        // 获取网络接口
        Status = getifaddrs(&interfaces);
        
        // 成功获取到
        if (Status == 0)
        {
            // 循环接口列表
            temp = interfaces;
            
            // 找到可用接口
            while(temp != NULL)
            {
                // 判断是否为可用接口
                if(temp->ifa_addr->sa_family == AF_INET)
                {
                    // 检查当前接口是否是WiFi接口
                    if([[NSString stringWithUTF8String:temp->ifa_name] isEqualToString:@"en0"])
                    {
                        // 获取 WiFi IP 地址
                        ipAddress = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp->ifa_addr)->sin_addr)];
                    }
                }
                
                // 设置临时接口为下一个接口
                temp = temp->ifa_next;
            }
        }
        
        // 释放接口列表内存
        freeifaddrs(interfaces);
        
        // 检查ip地址是否为空
        if (ipAddress == nil || ipAddress.length <= 0) {
            // 没有IP地址
            return nil;
        }
        
        // 返回WiFi的IP地址
        return ipAddress;
    }
    @catch (NSException *exception) {
        // 出现错误
        return nil;
    }
}

2. 获取蜂窝网的IP地址

//  获取蜂窝网的IP地址
+ (nullable NSString *)cellIPAddress {
    @try {
        // 初始化IP地址
        NSString *ipAddress;
        // 结构体记录接口和临时地址
        struct ifaddrs *interfaces;
        struct ifaddrs *temp;
        struct sockaddr_in *s4;
        char buf[64];
        
        // 成功获取
        if (!getifaddrs(&interfaces))
        {
            // 遍历接口列表
            temp = interfaces;
            while(temp != NULL)
            {
                // 临时接口是否有效
                if(temp->ifa_addr->sa_family == AF_INET)
                {
                    // 检查接口是不是蜂窝网
                    if([[NSString stringWithUTF8String:temp->ifa_name] isEqualToString:@"pdp_ip0"])
                    {
                        s4 = (struct sockaddr_in *)temp->ifa_addr;
                        
                        if (inet_ntop(temp->ifa_addr->sa_family, (void *)&(s4->sin_addr), buf, sizeof(buf)) == NULL) {
                            // 未找到
                            ipAddress = nil;
                        } else {
                            // 获取ip地址
                            ipAddress = [NSString stringWithUTF8String:buf];
                        }
                    }
                }
                
                // 设置临时地址下一个接口值
                temp = temp->ifa_next;
            }
        }
        
        // 释放接口内存
        freeifaddrs(interfaces);
        
        // 检查ip地址不为空
        if (ipAddress == nil || ipAddress.length <= 0) {
            // Empty, return not found
            return nil;
        }
        
        // 返回IP地址
        return ipAddress;
    }
    @catch (NSException *exception) {
        //错误或者IP地址未找到
        return nil;
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容