C++编程-3:实现并测试Android平台getifaddrs()函数获取本地IP地址

本文代码下载地址:https://download.csdn.net/download/zhuyunier/10322858

在Android NDK目录下的ifaddrs.h中虽然有getifaddrs()和freeifaddrs()函数的定义,但是却必须在API>=24下才能使用这两个函数,如下所示:

#if __ANDROID_API__ >= 24
void freeifaddrs(struct ifaddrs* __ptr) __INTRODUCED_IN(24);
int getifaddrs(struct ifaddrs** __list_ptr) __INTRODUCED_IN(24);
#endif /* __ANDROID_API__ >= 24 */

但是我们的项目现在API统一使用的是21,为了能够在我们现在的API状态下使用这两个函数,根据网上一些大佬给出的C语言实现完成了API的兼容,我尝试将C语言代码改写成C++版本的,编译运行通过,也获取到了本地IP,但不清楚这样修改是否正确,所以还是先贴出C语言版本的代码,后续再补充C++版本的。实现代码如下:

//ifaddrs.h
#ifndef	_IFADDRS_H_
#define	_IFADDRS_H_

struct ifaddrs {
	struct ifaddrs  *ifa_next;
	char		*ifa_name;
	unsigned int	 ifa_flags;
	struct sockaddr	*ifa_addr;
	struct sockaddr	*ifa_netmask;
	struct sockaddr	*ifa_dstaddr;
	void		*ifa_data;
};

/*
 * This may have been defined in <net/if.h>.  Note that if <net/if.h> is
 * to be included it must be included before this header file.
 */
#ifndef	ifa_broadaddr
#define	ifa_broadaddr	ifa_dstaddr	/* broadcast address interface */
#endif

#include <sys/cdefs.h>

__BEGIN_DECLS
extern int getifaddrs(struct ifaddrs **ifap);
extern void freeifaddrs(struct ifaddrs *ifa);
__END_DECLS

#endif

 

//ifaddrs.c
#include "ifaddrs.h"

#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>

typedef struct NetlinkList
{
    struct NetlinkList *m_next;
    struct nlmsghdr *m_data;
    unsigned int m_size;
} NetlinkList;

static int netlink_socket(void)
{
    int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
    if(l_socket < 0)
    {
        return -1;
    }
    
    struct sockaddr_nl l_addr;
    memset(&l_addr, 0, sizeof(l_addr));
    l_addr.nl_family = AF_NETLINK;
    if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0)
    {
        close(l_socket);
        return -1;
    }
    
    return l_socket;
}

static int netlink_send(int p_socket, int p_request)
{
    char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))];
    memset(l_buffer, 0, sizeof(l_buffer));
    struct nlmsghdr *l_hdr = (struct nlmsghdr *)l_buffer;
    struct rtgenmsg *l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr);
    
    l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg));
    l_hdr->nlmsg_type = p_request;
    l_hdr->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
    l_hdr->nlmsg_pid = 0;
    l_hdr->nlmsg_seq = p_socket;
    l_msg->rtgen_family = AF_UNSPEC;
    
    struct sockaddr_nl l_addr;
    memset(&l_addr, 0, sizeof(l_addr));
    l_addr.nl_family = AF_NETLINK;
    return (sendto(p_socket, l_hdr, l_hdr->nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr)));
}

static int netlink_recv(int p_socket, void *p_buffer, size_t p_len)
{
    struct msghdr l_msg;
    struct iovec l_iov = { p_buffer, p_len };
    struct sockaddr_nl l_addr;
    int l_result;

    for(;;)
    {
        l_msg.msg_name = (void *)&l_addr;
        l_msg.msg_namelen = sizeof(l_addr);
        l_msg.msg_iov = &l_iov;
        l_msg.msg_iovlen = 1;
        l_msg.msg_control = NULL;
        l_msg.msg_controllen = 0;
        l_msg.msg_flags = 0;
        int l_result = recvmsg(p_socket, &l_msg, 0);
        
        if(l_result < 0)
        {
            if(errno == EINTR)
            {
                continue;
            }
            return -2;
        }
        
        if(l_msg.msg_flags & MSG_TRUNC)
        { // buffer was too small
            return -1;
        }
        return l_result;
    }
}

static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_done)
{
    size_t l_size = 4096;
    void *l_buffer = NULL;
    
    for(;;)
    {
        free(l_buffer);
        l_buffer = malloc(l_size);
        
        int l_read = netlink_recv(p_socket, l_buffer, l_size);
        *p_size = l_read;
        if(l_read == -2)
        {
            free(l_buffer);
            return NULL;
        }
        if(l_read >= 0)
        {
            pid_t l_pid = getpid();
            struct nlmsghdr *l_hdr;
            for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read))
            {
                if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
                {
                    continue;
                }
                
                if(l_hdr->nlmsg_type == NLMSG_DONE)
                {
                    *p_done = 1;
                    break;
                }
                
                if(l_hdr->nlmsg_type == NLMSG_ERROR)
                {
                    free(l_buffer);
                    return NULL;
                }
            }
            return l_buffer;
        }
        
        l_size *= 2;
    }
}

static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size)
{
    NetlinkList *l_item = malloc(sizeof(NetlinkList));
    l_item->m_next = NULL;
    l_item->m_data = p_data;
    l_item->m_size = p_size;
    return l_item;
}

static void freeResultList(NetlinkList *p_list)
{
    NetlinkList *l_cur;
    while(p_list)
    {
        l_cur = p_list;
        p_list = p_list->m_next;
        free(l_cur->m_data);
        free(l_cur);
    }
}

static NetlinkList *getResultList(int p_socket, int p_request)
{
    if(netlink_send(p_socket, p_request) < 0)
    {
        return NULL;
    }

    NetlinkList *l_list = NULL;
    NetlinkList *l_end = NULL;
    int l_size;
    int l_done = 0;
    while(!l_done)
    {
        struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, &l_size, &l_done);
        if(!l_hdr)
        { // error
            freeResultList(l_list);
            return NULL;
        }
        
        NetlinkList *l_item = newListItem(l_hdr, l_size);
        if(!l_list)
        {
            l_list = l_item;
        }
        else
        {
            l_end->m_next = l_item;
        }
        l_end = l_item;
    }
    return l_list;
}

static size_t maxSize(size_t a, size_t b)
{
    return (a > b ? a : b);
}

static size_t calcAddrLen(sa_family_t p_family, int p_dataSize)
{
    switch(p_family)
    {
        case AF_INET:
            return sizeof(struct sockaddr_in);
        case AF_INET6:
            return sizeof(struct sockaddr_in6);
        case AF_PACKET:
            return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize);
        default:
            return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize);
    }
}

static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size)
{
    switch(p_family)
    {
        case AF_INET:
            memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size);
            break;
        case AF_INET6:
            memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size);
            break;
        case AF_PACKET:
            memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size);
            ((struct sockaddr_ll*)p_dest)->sll_halen = p_size;
            break;
        default:
            memcpy(p_dest->sa_data, p_data, p_size);
            break;
    }
    p_dest->sa_family = p_family;
}

static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry)
{
    if(!*p_resultList)
    {
        *p_resultList = p_entry;
    }
    else
    {
        struct ifaddrs *l_cur = *p_resultList;
        while(l_cur->ifa_next)
        {
            l_cur = l_cur->ifa_next;
        }
        l_cur->ifa_next = p_entry;
    }
}

static void interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_links, struct ifaddrs **p_resultList)
{
    struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr);

    size_t l_nameSize = 0;
    size_t l_addrSize = 0;
    size_t l_dataSize = 0;
    
    size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
    struct rtattr *l_rta;
    for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifinfomsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
    {
        void *l_rtaData = RTA_DATA(l_rta);
        size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
        switch(l_rta->rta_type)
        {
            case IFLA_ADDRESS:
            case IFLA_BROADCAST:
                l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize));
                break;
            case IFLA_IFNAME:
                l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
                break;
            case IFLA_STATS:
                l_dataSize += NLMSG_ALIGN(l_rtaSize);
                break;
            default:
                break;
        }
    }
    
    struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize + l_dataSize);
    memset(l_entry, 0, sizeof(struct ifaddrs));
    l_entry->ifa_name = "";
    
    char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
    char *l_addr = l_name + l_nameSize;
    char *l_data = l_addr + l_addrSize;
    
    l_entry->ifa_flags = l_info->ifi_flags;
    
    l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
    for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifinfomsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
    {
        void *l_rtaData = RTA_DATA(l_rta);
        size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
        switch(l_rta->rta_type)
        {
            case IFLA_ADDRESS:
            case IFLA_BROADCAST:
            {
                size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize);
                makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
                ((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index;
                ((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type;
                if(l_rta->rta_type == IFLA_ADDRESS)
                {
                    l_entry->ifa_addr = (struct sockaddr *)l_addr;
                }
                else
                {
                    l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
                }
                l_addr += NLMSG_ALIGN(l_addrLen);
                break;
            }
            case IFLA_IFNAME:
                strncpy(l_name, l_rtaData, l_rtaDataSize);
                l_name[l_rtaDataSize] = '\0';
                l_entry->ifa_name = l_name;
                break;
            case IFLA_STATS:
                memcpy(l_data, l_rtaData, l_rtaDataSize);
                l_entry->ifa_data = l_data;
                break;
            default:
                break;
        }
    }
    
    addToEnd(p_resultList, l_entry);
    p_links[l_info->ifi_index - 1] = l_entry;
}

static void interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_links, struct ifaddrs **p_resultList)
{
    struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr);

    size_t l_nameSize = 0;
    size_t l_addrSize = 0;
    
    int l_addedNetmask = 0;
    
    size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
    struct rtattr *l_rta;
    for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
    {
        void *l_rtaData = RTA_DATA(l_rta);
        size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
        if(l_info->ifa_family == AF_PACKET)
        {
            continue;
        }
        
        switch(l_rta->rta_type)
        {
            case IFA_ADDRESS:
            case IFA_LOCAL:
                if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask)
                { // make room for netmask
                    l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
                    l_addedNetmask = 1;
                }
            case IFA_BROADCAST:
                l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
                break;
            case IFA_LABEL:
                l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
                break;
            default:
                break;
        }
    }
    
    struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
    memset(l_entry, 0, sizeof(struct ifaddrs));
    l_entry->ifa_name = p_links[l_info->ifa_index - 1]->ifa_name;
    
    char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
    char *l_addr = l_name + l_nameSize;
    
    l_entry->ifa_flags = l_info->ifa_flags | p_links[l_info->ifa_index - 1]->ifa_flags;
    
    l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
    for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
    {
        void *l_rtaData = RTA_DATA(l_rta);
        size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
        switch(l_rta->rta_type)
        {
            case IFA_ADDRESS:
            case IFA_BROADCAST:
            case IFA_LOCAL:
            {
                size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize);
                makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
                if(l_info->ifa_family == AF_INET6)
                {
                    if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData))
                    {
                        ((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index;
                    }
                }
                
                if(l_rta->rta_type == IFA_ADDRESS)
                { // apparently in a point-to-point network IFA_ADDRESS contains the dest address and IFA_LOCAL contains the local address
                    if(l_entry->ifa_addr)
                    {
                        l_entry->ifa_dstaddr = (struct sockaddr *)l_addr;
                    }
                    else
                    {
                        l_entry->ifa_addr = (struct sockaddr *)l_addr;
                    }
                }
                else if(l_rta->rta_type == IFA_LOCAL)
                {
                    if(l_entry->ifa_addr)
                    {
                        l_entry->ifa_dstaddr = l_entry->ifa_addr;
                    }
                    l_entry->ifa_addr = (struct sockaddr *)l_addr;
                }
                else
                {
                    l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
                }
                l_addr += NLMSG_ALIGN(l_addrLen);
                break;
            }
            case IFA_LABEL:
                strncpy(l_name, l_rtaData, l_rtaDataSize);
                l_name[l_rtaDataSize] = '\0';
                l_entry->ifa_name = l_name;
                break;
            default:
                break;
        }
    }
    
    if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6))
    {
        unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128);
        unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen);
        char l_mask[16] = {0};
        unsigned i;
        for(i=0; i<(l_prefix/8); ++i)
        {
            l_mask[i] = 0xff;
        }
        l_mask[i] = 0xff << (8 - (l_prefix % 8));
        
        makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8);
        l_entry->ifa_netmask = (struct sockaddr *)l_addr;
    }
    
    addToEnd(p_resultList, l_entry);
}

static void interpret(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_links, struct ifaddrs **p_resultList)
{
    pid_t l_pid = getpid();
    for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
    {
        unsigned int l_nlsize = p_netlinkList->m_size;
        struct nlmsghdr *l_hdr;
        for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
        {
            if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
            {
                continue;
            }
            
            if(l_hdr->nlmsg_type == NLMSG_DONE)
            {
                break;
            }
            
            if(l_hdr->nlmsg_type == RTM_NEWLINK)
            {
                interpretLink(l_hdr, p_links, p_resultList);
            }
            else if(l_hdr->nlmsg_type == RTM_NEWADDR)
            {
                interpretAddr(l_hdr, p_links, p_resultList);
            }
        }
    }
}

static unsigned countLinks(int p_socket, NetlinkList *p_netlinkList)
{
    unsigned l_links = 0;
    pid_t l_pid = getpid();
    for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
    {
        unsigned int l_nlsize = p_netlinkList->m_size;
        struct nlmsghdr *l_hdr;
        for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
        {
            if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
            {
                continue;
            }
            
            if(l_hdr->nlmsg_type == NLMSG_DONE)
            {
                break;
            }
            
            if(l_hdr->nlmsg_type == RTM_NEWLINK)
            {
                ++l_links;
            }
        }
    }
    
    return l_links;
}

int getifaddrs(struct ifaddrs **ifap)
{
    if(!ifap)
    {
        return -1;
    }
    *ifap = NULL;
    
    int l_socket = netlink_socket();
    if(l_socket < 0)
    {
        return -1;
    }
    
    NetlinkList *l_linkResults = getResultList(l_socket, RTM_GETLINK);
    if(!l_linkResults)
    {
        close(l_socket);
        return -1;
    }
    
    NetlinkList *l_addrResults = getResultList(l_socket, RTM_GETADDR);
    if(!l_addrResults)
    {
        close(l_socket);
        freeResultList(l_linkResults);
        return -1;
    }
    
    unsigned l_numLinks = countLinks(l_socket, l_linkResults) + countLinks(l_socket, l_addrResults);
    struct ifaddrs *l_links[l_numLinks];
    memset(l_links, 0, l_numLinks * sizeof(struct ifaddrs *));
    
    interpret(l_socket, l_linkResults, l_links, ifap);
    interpret(l_socket, l_addrResults, l_links, ifap);

    freeResultList(l_linkResults);
    freeResultList(l_addrResults);
    close(l_socket);
    return 0;
}

void freeifaddrs(struct ifaddrs *ifa)
{
    struct ifaddrs *l_cur;
    while(ifa)
    {
        l_cur = ifa;
        ifa = ifa->ifa_next;
        free(l_cur);
    }
}

测试代码如下:

 

//get_addr.c
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <time.h>  
#include <sys/types.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>  
#include "ifaddrs.h"
  
int main(int argc, char* argv[]){  
    struct ifaddrs *ifc, *ifc1;  
    char ip[64] = {};  
    char nm[64] = {};  
  
    if(0 != getifaddrs(&ifc)) return -1;  
    ifc1 = ifc;  
  
    printf("iface\tIP address\tNetmask\n");  
    for(; NULL != ifc; ifc = (*ifc).ifa_next){  
        printf("%s", (*ifc).ifa_name);  
        if(NULL != (*ifc).ifa_addr) {  
            inet_ntop(AF_INET, &(((struct sockaddr_in*)((*ifc).ifa_addr))->sin_addr), ip, 64);  
            printf("\t%s", ip);  
        }else{  
            printf("\t\t");  
        }  
        if(NULL != (*ifc).ifa_netmask){  
            inet_ntop(AF_INET, &(((struct sockaddr_in*)((*ifc).ifa_netmask))->sin_addr), nm, 64);  
            printf("\t%s", nm);  
        }else{  
            printf("\t\t");  
        }  
        printf("\n");  
    }  
  
    //freeifaddrs(ifc);  
    freeifaddrs(ifc1);  
    return 0;  
} 

代码完成后还需要测试下具体是否实现了获取本地IP的功能,首先在虚拟机下搭建Android平台的编译环境,将ifaddrs.h、ifaddrs.c、get_addr.c三个文件放在同一目录下。

 使用下面命令生成可执行文件get_addr:

/usr/android/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc --sysroot=/usr/android/android-ndk-r14b/platforms/android-16/arch-arm/ ifaddrs.c get_addr.c -o get_addr -pie -fPIE


打开Android Studio,使用adb将刚才生成的get_addrc文件拷贝到手机中,具体操作如下:

E:\test\Android_player\CTTStreamingPlayer>adb push get_addr /sdcard/      //通过adb push到sdcard上
get_addr: 1 file pushed. 0.1 MB/s (15704 bytes in 0.156s)

E:\test\Android_player\CTTStreamingPlayer>adb shell                       //进入shell模式
shell@gts28wifichn:/ $ cp /sdcard/get_addr /data/local/tmp/               //从sdcard复制到/data/local/tmp 下         
shell@gts28wifichn:/ $ cd /data/local/tmp
shell@gts28wifichn:/data/local/tmp $ chmod 751 get_addr                   //chmod 751 设置可执行程序权限
shell@gts28wifichn:/data/local/tmp $ ./get_addr                           //执行
iface   IP address      Netmask
lo      1.0.0.0
sit0    2.0.0.0
ip6tnl0 3.0.0.0
p2p0    4.0.0.0
wlan0   5.0.0.0
lo      127.0.0.1       255.0.0.0
wlan0   192.168.2.106   255.255.255.0
lo      0.0.0.0 0.0.0.0
p2p0    0.0.0.0 0.0.0.0
wlan0   0.0.0.0 0.0.0.0
shell@gts28wifichn:/data/local/tmp $

 

 

 

 

参考文章:https://blog.csdn.net/ryfdizuo/article/details/28891649

https://github.com/morristech/android-ifaddrs

 

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值