手机版 收藏 导航

C 语言如何编写一个能同时获取 IPv4 和 IPv6 地址的程序_用 C 语言获取本地 IP 地址的代码在不同操作系统上有什么区别

原创   www.link114.cn   2024-09-04 11:07:15

C 语言如何编写一个能同时获取 IPv4 和 IPv6 地址的程序_用 C 语言获取本地 IP 地址的代码在不同操作系统上有什么区别

要同时获取 IPv4 和 IPv6 地址,可以使用 POSIX 标准中的 getaddrinfo() 函数。这个函数能够返回一个链表结构,其中包含主机的所有地址信息。我们可以遍历这个链表,分别获取 IPv4 和 IPv6 地址。下面是一个示例代码:


#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

int main() {
    struct addrinfo *result, *rp;
    int s;

    s = getaddrinfo(NULL, "0", NULL, &result);
    if (s != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
        exit(EXIT_FAILURE);
    }

    for (rp = result; rp != NULL; rp = rp->ai_next) {
        if (rp->ai_family == AF_INET) {
            printf("IPv4 address: %s\n", inet_ntoa(((struct sockaddr_in *)rp->ai_addr)->sin_addr));
        } else if (rp->ai_family == AF_INET6) {
            char ipv6[INET6_ADDRSTRLEN];
            inet_ntop(AF_INET6, &((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr, ipv6, INET6_ADDRSTRLEN);
            printf("IPv6 address: %s\n", ipv6);
        }
    }

    freeaddrinfo(result);
    return 0;
}

在不同的操作系统上获取本地 IP 地址的代码也会略有不同。在 Windows 系统上,可以使用 GetAdaptersInfo() 函数来获取网卡信息。而在 Unix/Linux 系统上,可以使用 getifaddrs() 函数来获取网卡信息。下面是一个跨平台的示例代码:


#ifdef _WIN32
#include <winsock2.h>
#include <iphlpapi.h>
#pragma comment(lib, "iphlpapi.lib")
#else
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif

void get_local_ip(char *ip, int size) {
#ifdef _WIN32
    IP_ADAPTER_INFO *pAdapterInfo;
    ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
    pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
        free(pAdapterInfo);
        pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
        GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
    }
    strcpy_s(ip, size, pAdapterInfo->IpAddressList.IpAddress.String);
    free(pAdapterInfo);
#else
    struct ifaddrs *ifaddr, *ifa;
    int family, s;
    char host[NI_MAXHOST];

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

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

        family = ifa->ifa_addr->sa_family;
        if (family == AF_INET) {
            s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
            if (s != 0) {
                printf("getnameinfo() failed: %s\n", gai_strerror(s));
                return;
            }
            strcpy(ip, host);
            break;
        }
    }

    freeifaddrs(ifaddr);
#endif
}

使用 C 语言获取 IPv4 和 IPv6 地址以及本地 IP 地址的代码在不同操作系统上会有一些差异。但通过使用跨平台的函数和库,我们可以编写出可以在多个平台上运行的程序。