创建了一个网络类,来读取外网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;
}
}