iOS 如何获取手机外网IP地址(附内网IP地址)

查找了一些方法,最初以为拿到的就是手机对外的公网地址,其实只是本地IP地址。下面把获取手机内外网IP地址的方法总结下:

一、获取手机本地静态IP地址:(局域网)

方法1:

首先导入头文件:

//IP地址需求库
#import <sys/socket.h>
#import <sys/sockio.h>
#import <sys/ioctl.h>
#import <net/if.h>
#import <arpa/inet.h>

具体方法:

//获取设备IP地址
-(NSString *)getDeviceIPAddresses
{
    int sockfd = socket(AF_INET,SOCK_DGRAM, 0);
    // if (sockfd <</span> 0) return nil; //这句报错,由于转载的,不太懂,注释掉无影响,懂的大神欢迎指导
    NSMutableArray *ips = [NSMutableArray array];

    int BUFFERSIZE =4096;
    
    struct ifconf ifc;
    
    char buffer[BUFFERSIZE], *ptr, lastname[IFNAMSIZ], *cptr;
    
    struct ifreq *ifr, ifrcopy;
    
    ifc.ifc_len = BUFFERSIZE;
    
    ifc.ifc_buf = buffer;
    
    if (ioctl(sockfd,SIOCGIFCONF, &ifc) >= 0){
        
        for (ptr = buffer; ptr < buffer + ifc.ifc_len; ){
            
            ifr = (struct ifreq *)ptr;
            
            int len =sizeof(struct sockaddr);
            
            if (ifr->ifr_addr.sa_len > len) {
                len = ifr->ifr_addr.sa_len;
            }
            
            ptr += sizeof(ifr->ifr_name) + len;
            
            if (ifr->ifr_addr.sa_family !=AF_INET) continue;
            
            if ((cptr = (char *)strchr(ifr->ifr_name,':')) != NULL) *cptr =0;
            
            if (strncmp(lastname, ifr->ifr_name,IFNAMSIZ) == 0)continue;
            
            memcpy(lastname, ifr->ifr_name,IFNAMSIZ);
            
            ifrcopy = *ifr;
            
            ioctl(sockfd,SIOCGIFFLAGS, &ifrcopy);
            
            if ((ifrcopy.ifr_flags &IFF_UP) == 0)continue;

            NSString *ip = [NSString stringWithFormat:@"%s",inet_ntoa(((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr)];
            [ips addObject:ip];
        }
    }
    close(sockfd);

    NSString *deviceIP =@"";
    
    for (int i=0; i < ips.count; i++){
        if (ips.count >0){
            deviceIP = [NSString stringWithFormat:@"%@",ips.lastObject];
        }
    }
    
    return deviceIP;
}

参考:http://blog.sina.com.cn/s/blog_b0b335e20102y3im.html

 

方法2:

导入两个头文件,此法只能获取到WiFi环境下的本地IP,比较简洁

#import <ifaddrs.h>
#import <arpa/inet.h>
+ (NSString *)deviceIPAdress {
    NSString *address = @"手机移动网络";
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;
    
    success = getifaddrs(&interfaces);
    if (success == 0) {
        temp_addr = interfaces;
        while (temp_addr != NULL) {
            if( (*temp_addr).ifa_addr->sa_family == AF_INET) {
                if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {
                    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
                }
            }
            
            temp_addr = temp_addr->ifa_next;
        }
    }
    freeifaddrs(interfaces);
    
    //    NSLog(@"手机的IP是:%@", address);
    
    return address;
}

 

二、获取手机外网IP(公网IP)

网上找了很久获取外网IP的方法,很多访问网址已经不能用了,能用的主要有2个,但是获取到的IP地址不同,下面详细介绍。

方法1:此前采用的淘宝接口现在更改了不能用了,更新一下:

https://www.taobao.com/help/getip.php

https://www.fbisb.com/ip.php

这两个都可以,速度也比较快,但是与百度搜索IP的结果不一样,自取。

 

方法2:此方法访问的搜狐的获取ip接口,返回的IP与百度淘宝不一样。

-(NSString *)getWANIPAddress
{
    NSError *error;
    NSURL *ipURL = [NSURL URLWithString:@"http://pv.sohu.com/cityjson?ie=utf-8"];
    
    NSMutableString *ip = [NSMutableString stringWithContentsOfURL:ipURL encoding:NSUTF8StringEncoding error:&error];
    //判断返回字符串是否为所需数据
    if ([ip hasPrefix:@"var returnCitySN = "]) {
        //对字符串进行处理,然后进行json解析
        //删除字符串多余字符串
        NSRange range = NSMakeRange(0, 19);
        [ip deleteCharactersInRange:range];
        NSString * nowIp =[ip substringToIndex:ip.length-1];
        //将字符串转换成二进制进行Json解析
        NSData * data = [nowIp dataUsingEncoding:NSUTF8StringEncoding];
        NSDictionary * dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"%@",dict);
        return dict[@"cip"] ? dict[@"cip"] : @"";
    }
    return @"";
}

 

访问接口取到的数据:

参考:http://blog.csdn.net/henry_moneybag/article/details/51463375
 

还有一个接口可直接获取到IP,但返回比较慢,可能返回失败,不推荐。特点是结果与百度搜索ip的结果一致。

    NSError *error;
    NSURL *ipURL = [NSURL URLWithString:@"http://ifconfig.me/ip"];
    NSString *ip = [NSString stringWithContentsOfURL:ipURL encoding:NSUTF8StringEncoding error:&error];

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
获取手机SSID和BSSID可以使用iOS的System Configuration框架中的Captive Network API,具体代码如下: ```swift import SystemConfiguration.CaptiveNetwork func getWifiInfo() -> (ssid: String?, bssid: String?) { var ssid: String? var bssid: String? if let interfaces = CNCopySupportedInterfaces() as NSArray? { for interface in interfaces { if let interfaceInfo = CNCopyCurrentNetworkInfo(interface as! CFString) as NSDictionary? { ssid = interfaceInfo[kCNNetworkInfoKeySSID as String] as? String bssid = interfaceInfo[kCNNetworkInfoKeyBSSID as String] as? String } } } return (ssid, bssid) } ``` 获取IP地址可以使用iOS的网络接口API,具体代码如下: ```swift import UIKit import SystemConfiguration func getIPAddress() -> String? { var address: String? var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil if getifaddrs(&ifaddr) == 0 { var ptr = ifaddr while ptr != nil { let flags = Int32(ptr!.pointee.ifa_flags) var addr = ptr!.pointee.ifa_addr.pointee if ((flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING)) && (addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6)) { var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) if (getnameinfo(&addr, socklen_t(addr.sa_len), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST) == 0) { if let addressString = String(validatingUTF8:hostname) { if addr.sa_family == UInt8(AF_INET) { address = addressString } } } } ptr = ptr!.pointee.ifa_next } freeifaddrs(ifaddr) } return address } ``` 注意,获取IP地址需要在应用的Info.plist文件中添加`Privacy - Local Network Usage Description`键,并在值中添加描述,否则应用将被拒绝。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值