美文网首页搬砖iOS 知识点
iOS获取手机IP地址

iOS获取手机IP地址

作者: 风外杏林香 | 来源:发表于2018-04-18 10:17 被阅读1521次

    项目中又遇到要将手机网络IP地址传参到服务器由于之前没有做过,记录下遇到的问题,手机IP地址分为俩种情况,WiFi网络IP地址和蜂窝移动网络IP地址。
    1、WiFi地址(类方法直接调用,可以直接写进网络框架里面),这种只有当手机连接到WiFi时候可用,否则返回为error,

    + (NSString *)getIPAddress {      
        NSString *address = @"error";  
        struct ifaddrs *interfaces = NULL;  
        struct ifaddrs *temp_addr = NULL;  
        int success = 0;  
        // retrieve the current interfaces - returns 0 on success  
        success = getifaddrs(&interfaces);  
        if (success == 0) {  
            // Loop through linked list of interfaces  
            temp_addr = interfaces;  
            while(temp_addr != NULL) {  
                if(temp_addr->ifa_addr->sa_family == AF_INET) {  
                    // Check if interface is en0 which is the wifi connection on the iPhone  
                    if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {  
                        // Get NSString from C String  
                        address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];                 
                    }  
                }  
                temp_addr = temp_addr->ifa_next;  
            }  
        }  
        // Free memory  
        freeifaddrs(interfaces);  
        return address;  
    }   
    

    2、WiFi和蜂窝移动网络通用(创建继承于NSObject类 JCIPAddressConfig

    JCIPAddressConfig.h中
    #import <Foundation/Foundation.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/ioctl.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    #include <sys/sockio.h>
    #include <net/if.h>
    #include <errno.h>
    #include <net/if_dl.h>
    #include <net/ethernet.h>
    #include <ifaddrs.h>
    #include <arpa/inet.h>
    
    #define BUFFERSIZE  4000
    #define MAXADDRS    32
    #define min(a,b)    ((a) < (b) ? (a) : (b))
    #define max(a,b)    ((a) > (b) ? (a) : (b))
    
    @interface JCIPAddressConfig : NSObject
    // extern
    extern char *if_names[MAXADDRS];
    extern char *ip_names[MAXADDRS];
    extern char *hw_addrs[MAXADDRS];
    extern unsigned long ip_addrs[MAXADDRS];
    
    // Function prototypes
    void InitAddresses();
    void FreeAddresses();
    void GetIPAddresses();
    void GetHWAddresses();
    @end
    JCIPAddressConfig.m中
    @implementation JCIPAddressConfig
    char *if_names[MAXADDRS];
    char *ip_names[MAXADDRS];
    char *hw_addrs[MAXADDRS];
    unsigned long ip_addrs[MAXADDRS];
    static int   nextAddr = 0;
    void InitAddresses() {
        int i;
        for (i=0; i<MAXADDRS; ++i) {
            if_names[i] = ip_names[i] = hw_addrs[i] = NULL;
            ip_addrs[i] = 0;
        }
    }
    
    void FreeAddresses() {
        int i;
        for (i=0; i<MAXADDRS; ++i) {
            if (if_names[i] != 0) free(if_names[i]);
            if (ip_names[i] != 0) free(ip_names[i]);
            if (hw_addrs[i] != 0) free(hw_addrs[i]);
            ip_addrs[i] = 0;
        }
        InitAddresses();
    }
    
    void GetIPAddresses() {
        int                 i, len, flags;
        char                buffer[BUFFERSIZE], *ptr, lastname[IFNAMSIZ], *cptr;
        struct ifconf       ifc;
        struct ifreq        *ifr, ifrcopy;
        struct sockaddr_in  *sin;
        char temp[80];
        int sockfd;
        for (i=0; i<MAXADDRS; ++i) {
            if_names[i] = ip_names[i] = NULL;
            ip_addrs[i] = 0;
        }
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sockfd < 0) {
            perror("socket failed");
            return;
        }
        ifc.ifc_len = BUFFERSIZE;
        ifc.ifc_buf = buffer;
        if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
            perror("ioctl error");
            return;
        }
        lastname[0] = 0;
        for (ptr = buffer; ptr < buffer + ifc.ifc_len; ) {
            ifr = (struct ifreq *)ptr;
            len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);
            ptr += sizeof(ifr->ifr_name) + len;   // for next one in buffer
            
            if (ifr->ifr_addr.sa_family != AF_INET) {
                continue; // ignore if not desired address family
            }
            
            if ((cptr = (char *)strchr(ifr->ifr_name, ':')) != NULL)  {
                *cptr = 0;        // replace colon will null
            }
            
            if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {
                continue; /* already processed this interface */
            }
            memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
            ifrcopy = *ifr;
            ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);
            flags = ifrcopy.ifr_flags;
            if ((flags & IFF_UP) == 0){
                continue; // ignore if interface not up
            }
            if_names[nextAddr] = (char *)malloc(strlen(ifr->ifr_name)+1);
            if (if_names[nextAddr] == NULL){
                return;
            }
            strcpy(if_names[nextAddr], ifr->ifr_name);
            sin = (struct sockaddr_in *)&ifr->ifr_addr;
            strcpy(temp, inet_ntoa(sin->sin_addr));
            ip_names[nextAddr] = (char *)malloc(strlen(temp)+1);
            if (ip_names[nextAddr] == NULL) {
                return;
            }
            strcpy(ip_names[nextAddr], temp);
            ip_addrs[nextAddr] = sin->sin_addr.s_addr;
            ++nextAddr;
        }
        close(sockfd);
    }
    
    void GetHWAddresses(){
        struct ifconf ifc;
        struct ifreq *ifr;
        int i, sockfd;
        char buffer[BUFFERSIZE], *cp, *cplim;
        char temp[80];
        for (i=0; i<MAXADDRS; ++i) {
            hw_addrs[i] = NULL;
        }
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sockfd < 0) {
            perror("socket failed");
            return;
        }
        
        ifc.ifc_len = BUFFERSIZE;
        ifc.ifc_buf = buffer;
        if (ioctl(sockfd, SIOCGIFCONF, (char *)&ifc) < 0) {
            perror("ioctl error");
            close(sockfd);
            return;
        }
        ifr = ifc.ifc_req;
        cplim = buffer + ifc.ifc_len;
        for (cp=buffer; cp < cplim; ) {
            ifr = (struct ifreq *)cp;
            if (ifr->ifr_addr.sa_family == AF_LINK) {
                struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
                int a,b,c,d,e,f;
                int i;
                strcpy(temp, (char *)ether_ntoa((const struct ether_addr *)LLADDR(sdl)));
                sscanf(temp, "%x:%x:%x:%x:%x:%x", &a, &b, &c, &d, &e, &f);
                sprintf(temp, "%02X:%02X:%02X:%02X:%02X:%02X",a,b,c,d,e,f);
                
                for (i=0; i<MAXADDRS; ++i){
                    if ((if_names[i] != NULL) && (strcmp(ifr->ifr_name, if_names[i]) == 0)) {
                        if (hw_addrs[i] == NULL){
                            hw_addrs[i] = (char *)malloc(strlen(temp)+1);
                            strcpy(hw_addrs[i], temp);
                            break;
                        }
                    }
                }
            }
            cp += sizeof(ifr->ifr_name) + max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len);
        }
        close(sockfd);
    }
    @end
    网络请求类.h中,声明获取IP地址类方法
    /*
     * 获取设备IP地址
     */
    + (NSString *)getIPAddress:(BOOL)preferIPv4;
    网络请求类.m中,实现方法
    /*
     * 获取设备IP地址
     */
    + (NSString *)getIPAddress:(BOOL)preferIPv4
    {
        NSArray *searchArray = preferIPv4 ?
        @[ IOS_VPN @"/" IP_ADDR_IPv4, /*IOS_VPN @"/" IP_ADDR_IPv6, */IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] :
        @[ IOS_VPN @"/" IP_ADDR_IPv6, IOS_VPN @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ];//此处我只需要IPv4地址,并不需要IPv6所以不需要直接不用
        NSDictionary *addresses = [self getIPAddresses];
        JCLog(@"addresses: %@", addresses);
        __block NSString *address;
        [searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop)
         {
             address = addresses[key];
             if(address) *stop = YES;
         } ];
        return address ? address : @"0.0.0.0";
    }
    + (NSDictionary *)getIPAddresses
    {
        NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
        // retrieve the current interfaces - returns 0 on success
        struct ifaddrs *interfaces;
        if(!getifaddrs(&interfaces)) {
            // Loop through linked list of interfaces
            struct ifaddrs *interface;
            for(interface=interfaces; interface; interface=interface->ifa_next) {
                if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) {
                    continue; // deeply nested code harder to read
                }
                const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;
                char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
                if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
                    NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
                    NSString *type;
                    if(addr->sin_family == AF_INET) {
                        if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
                            type = IP_ADDR_IPv4;
                        }
                    } else {
                        const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr;
                        if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {
                            type = IP_ADDR_IPv6;
                        }
                    }
                    if(type) {
                        NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
                        addresses[key] = [NSString stringWithUTF8String:addrBuf];
                    }
                }
            }
            // Free memory
            freeifaddrs(interfaces);
        }
        return [addresses count] ? addresses : nil;
    }
    

    到此获取手机IP地址完成,方法一只能获取到WiFi地址,方法二俩种都能获取到
    附上demo地址,欢迎star😂😂😂

    相关文章

      网友评论

        本文标题:iOS获取手机IP地址

        本文链接:https://www.haomeiwen.com/subject/riamkftx.html