C语言封装获取本机IP地址的程序

发布于:2024-06-24 ⋅ 阅读:(151) ⋅ 点赞:(0)

0.概要

本文介绍用C语言编写一个函数来获取本机的IP地址。

1. 设计

将获取IP地址的逻辑封装到一个独立的函数中,并定义一个结构体来存储IP地址和接口名称。
将获取IP地址的逻辑封装到一个函数中,该函数遍历本机的所有网络接口并获取其IP地址.

2. 完整的代码

完整的代码如下:

ip_address.h

#ifndef IP_ADDRESS_H
#define IP_ADDRESS_H

#include <netinet/in.h>
#include <net/if.h>

#define MAX_IP_ADDRESSES 50
#define INET6_ADDRSTRLEN 46

typedef struct {
    char ifa_name[IFNAMSIZ];
    char ip_address[INET6_ADDRSTRLEN];
    int family;
} IPAddress;

int get_ip_addresses(IPAddress *ip_addresses, int max_addresses);

#endif // IP_ADDRESS_H

ip_address.c

#include "ip_address.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>

int get_ip_addresses(IPAddress *ip_addresses, int max_addresses) {
    struct ifaddrs *ifAddrStruct = NULL;
    struct ifaddrs *ifa = NULL;
    void *tmpAddrPtr = NULL;
    int count = 0;

    if (getifaddrs(&ifAddrStruct) == -1) {
        /* Error handling */
        return -1;
    }

    for (ifa = ifAddrStruct; ifa != NULL && count < max_addresses; ifa = ifa->ifa_next) {
        if (ifa->ifa_addr == NULL) {
            continue;
        }

        int family = ifa->ifa_addr->sa_family;
        if (family == AF_INET) {
            tmpAddrPtr = &((struct sockaddr_in *)(ifa->ifa_addr))->sin_addr;
            if (inet_ntop(AF_INET, tmpAddrPtr, ip_addresses[count].ip_address, INET_ADDRSTRLEN) != NULL) {
                strncpy(ip_addresses[count].ifa_name, ifa->ifa_name, IFNAMSIZ);
                ip_addresses[count].family = AF_INET;
                count++;
            }
        } else if (family == AF_INET6) {
            tmpAddrPtr = &((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_addr;
            if (inet_ntop(AF_INET6, tmpAddrPtr, ip_addresses[count].ip_address, INET6_ADDRSTRLEN) != NULL) {
                strncpy(ip_addresses[count].ifa_name, ifa->ifa_name, IFNAMSIZ);
                ip_addresses[count].family = AF_INET6;
                count++;
            }
        } else {
            /* Do nothing */
        }
    }

    freeifaddrs(ifAddrStruct);

    return count;
}

main.c

#include <stdio.h>
#include "ip_address.h"

int main(void) {
    IPAddress ip_addresses[MAX_IP_ADDRESSES];
    int count = get_ip_addresses(ip_addresses, MAX_IP_ADDRESSES);

    if (count == -1) {
        fprintf(stderr, "Failed to get IP addresses.\n");
        return 1;
    }

    for (int i = 0; i < count; i++) {
        if (ip_addresses[i].family == AF_INET) {
            printf("%s IPv4 Address: %s\n", ip_addresses[i].ifa_name, ip_addresses[i].ip_address);
        } else if (ip_addresses[i].family == AF_INET6) {
            printf("%s IPv6 Address: %s\n", ip_addresses[i].ifa_name, ip_addresses[i].ip_address);
        }
    }

    return 0;
}

编译命令

gcc -o ip_address main.c ip_address.c

执行结果

test@t:~/ip_address$ ./ip_address 
lo IPv4 Address: 127.0.0.1
ens33 IPv4 Address: 192.168.1.10
lo IPv6 Address: ::1
ens33 IPv6 Address: 2409:8a20:4e3c:d460:20c:29ff:feb3:d386
ens33 IPv6 Address: fe80::20c:29ff:feb3:d386

通过上述步骤,你将能够获取并打印本机的所有IPv4和IPv6地址。