千锋教育-做有情怀、有良心、有品质的职业教育机构

手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

当前位置:首页  >  技术干货  > 深入了解getifaddrs函数

深入了解getifaddrs函数

来源:千锋教育
发布人:xqq
时间: 2023-11-24 23:09:21 1700838561

一、getifaddrs简介

getifaddrs是一种系统级函数,可用于检索网络接口的地址信息。其定义在ifaddrs.h头文件中。该函数通过动态分配存储空间来保存设备地址列表。通常情况下,您需要使用freeifaddrs函数释放该列表。


struct ifaddrs {
    struct ifaddrs  *ifa_next;         /* 下一个地址 */
    char            *ifa_name;         /* 名称,任务类型,和类型信息 */
    unsigned int     ifa_flags;        /* 属性 */
    struct sockaddr *ifa_addr;         /* 地址信息 */
    struct sockaddr *ifa_netmask;      /* 网络掩码 */
    union {
        struct sockaddr *ifu_broadaddr;
                     /* 广播地址 */
        struct sockaddr *ifu_dstaddr;
                     /* 目标地址 */
    } ifa_ifu;
#define              ifa_broadaddr ifa_ifu.ifu_broadaddr
#define              ifa_dstaddr   ifa_ifu.ifu_dstaddr
    void            *ifa_data;         /* 地址信息 */
};

二、使用getifaddrs函数

下面是使用getifaddrs函数的基本步骤:

1、定义一个ifaddrs类型指针,用于存储指向设备地址列表的第一个元素的指针。

2、调用getifaddrs函数,并将指向ifaddrs类型指针的指针传递给函数。

3、遍历设备地址列表,并执行所需操作。

4、最终执行freeifaddrs函数,以释放分配给设备地址列表的存储空间。

三、getifaddrs的特性

1、获取网络接口信息

使用getifaddrs函数可获取网络接口的信息,包括接口名称、IP地址、子网掩码等。此外,还可以轻松获取相关的网络接口的广播地址和目标地址。


struct ifaddrs *ifaddr, *ifa;
int family, s;
char host[NI_MAXHOST];

if (getifaddrs(&ifaddr) == -1) {
    perror("getifaddrs");
    exit(EXIT_FAILURE);
}

for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
    if (ifa->ifa_addr == NULL)
        continue;

    family = ifa->ifa_addr->sa_family;

    /* 显示地址族(针对IPV4和IPV6),IPV4地址和端口号,IPV6地址和端口号,并将地址存储在host数组中 */
    if (family == AF_INET || family == AF_INET6) {
        s = getnameinfo(ifa->ifa_addr,
                        (family == AF_INET) ? sizeof(struct sockaddr_in) :
                                              sizeof(struct sockaddr_in6),
                        host, NI_MAXHOST,
                        NULL, 0, NI_NUMERICHOST);
        if (s != 0) {
            printf("getnameinfo() failed: %s\n", gai_strerror(s));
            exit(EXIT_FAILURE);
        }

        printf("%s  address: %s\n", ifa->ifa_name, host);
    }
}

freeifaddrs(ifaddr);

2、实现TCP/IP Server / Client 套接字列表

使用getifaddrs函数,可以轻松实现TCP/IP服务器和客户端套接字列表。下面是实现TCP/IP服务器/客户端套接字列表的代码示例。


int sockfd, status, s, max_fds = 0;
struct addrinfo hints, *servinfo, *p;
struct ifaddrs *ifaddr, *ifa;

/* 获取可用地址列表 */
getifaddrs(&ifaddr);

/* 循环连接可用地址 */
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
    if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET) {
        continue;
    }

    /* 定义TCP/IP Socket服务器地址 */
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;          /* IPV4 */
    hints.ai_socktype = SOCK_STREAM;    /* 流套接字(比如TCP) */
    hints.ai_flags = AI_PASSIVE;        /* 意味着底层套接字地址将被用于bind调用中data */

    /* 获取可用服务器地址 */
    s = getaddrinfo(NULL, "8080", &hints, &servinfo);
    if (s != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
        return -1;
    }

    /* 循环连接可用地址 */
    for (p = servinfo; p != NULL; p = p->ai_next) {
        /* 创建TCP/IP Socket */
        sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
        if (sockfd < 0) {
            continue;
        }

        /* 确认连接 */
        status = connect(sockfd, p->ai_addr, p->ai_addrlen);
        if (status < 0) {
            close(sockfd);
            continue;
        }

        /* 监听客户端 */
        status = listen(sockfd, 10);
        if (status < 0) {
            close(sockfd);
            continue;
        }

        /* 记录最大的文件描述符号码 */
        max_fds = MAX(max_fds, sockfd);
    }

    /* free the list */
    freeaddrinfo(servinfo);
}

freeifaddrs(ifaddr);

四、Getifaddrs崩溃

在使用getifaddrs时,一些安全漏洞可能导致崩溃。应该注意以下问题:

1、内存泄漏

必须使用freeifaddrs函数显式释放分配的内存。否则可能会导致内存泄漏。

2、缓冲区溢出

缓冲区溢出是指将输入数据存储在内存缓冲区之外的情况。这可能导致程序失败或崩溃。可以使用lwip中的替代方案lwip_getifaddrs避免此问题。

结论

getifaddrs是一种用于检索网络接口地址信息的系统级函数。通过动态分配存储空间来保存设备地址列表。使用该函数,您可以轻松实现TCP/IP服务器和客户端套接字列表、获取网络接口信息等。但是,在使用getifaddrs时,必须注意避免内存泄漏和缓冲区溢出引起的崩溃问题。

tags: gmpy2
声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。
10年以上业内强师集结,手把手带你蜕变精英
请您保持通讯畅通,专属学习老师24小时内将与您1V1沟通
免费领取
今日已有369人领取成功
刘同学 138****2860 刚刚成功领取
王同学 131****2015 刚刚成功领取
张同学 133****4652 刚刚成功领取
李同学 135****8607 刚刚成功领取
杨同学 132****5667 刚刚成功领取
岳同学 134****6652 刚刚成功领取
梁同学 157****2950 刚刚成功领取
刘同学 189****1015 刚刚成功领取
张同学 155****4678 刚刚成功领取
邹同学 139****2907 刚刚成功领取
董同学 138****2867 刚刚成功领取
周同学 136****3602 刚刚成功领取
相关推荐HOT