转自:http://blog.csdn.net/txz_gray/article/details/53217293
查找了一些方法,最初以为拿到的就是手机对外的公网地址,其实只是本地IP地址。下面把获取手机内外网IP地址的方法总结下:
一、获取手机本地静态IP地址:(局域网)
方法1:
首先导入头文件:
-
- #import <sys/socket.h>
- #import <sys/sockio.h>
- #import <sys/ioctl.h>
- #import <net/if.h>
- #import <arpa/inet.h>
具体方法:
-
- -(NSString *)getDeviceIPAddresses
- {
- int sockfd = socket(AF_INET,SOCK_DGRAM, 0);
-
- 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 = (charchar *)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);
-
-
-
- return address;
- }
二、获取手机外网IP(公网IP)
网上找了很久获取外网IP的方法,很多访问网址已经不能用了,能用的主要有2个,但是获取到的IP地址不同,下面详细介绍。
首推方法1:此方法采用的淘宝网址,获取的到IP与百度IP是一样的,考虑到如今百度横行,所以我使用的是此方法。
- -(NSString *)deviceWANIPAddress
- {
- NSURL *ipURL = [NSURL URLWithString:@"http://ip.taobao.com/service/getIpInfo.php?ip=myip"];
- NSData *data = [NSData dataWithContentsOfURL:ipURL];
- NSDictionary *ipDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
- NSString *ipStr = nil;
- if (ipDic && [ipDic[@"code"] integerValue] == 0) {
- ipStr = ipDic[@"data"][@"ip"];
- }
- return (ipStr ? ipStr : @"");
- }
访问接口返回的json数据:
百度ip查到的本机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 = "]) {
-
-
- NSRange range = NSMakeRange(0, 19);
- [ip deleteCharactersInRange:range];
- NSString * nowIp =[ip substringToIndex:ip.length-1];
-
- 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,但返回比较慢,可能返回失败,不推荐。
- NSError *error;
- NSURL *ipURL = [NSURL URLWithString:@"http://ifconfig.me/ip"];
- NSString *ip = [NSString stringWithContentsOfURL:ipURL encoding:NSUTF8StringEncoding error:&error];