当前位置:首页 > 行业动态 > 正文

如何在C Linux中获取本机的IP地址?

在Linux系统中,可以使用 ifconfig或 ip addr命令来获取本机的IP地址。,,“ bash,ifconfig,` ,,或者,,` bash,ip addr,“,,这些命令会显示网络接口的详细信息,包括IP地址。

C语言在Linux下获取本机IP地址

如何在C Linux中获取本机的IP地址?  第1张

一、使用getifaddrs函数获取本机IP地址

getifaddrs函数是Linux系统中用于获取主机网络接口地址的常用方法,它返回一个链表,每个节点包含一个接口的信息,包括IP地址、子网掩码等,以下是使用该函数获取本机IP地址的示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main() {
    struct ifaddrs *ifAddrStruct = NULL;
    struct ifaddrs *ifa = NULL;
    void *tmpAddrPtr = NULL;
    getifaddrs(&ifAddrStruct);
    for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
        if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) { // check it is IP4
            // is a valid IP4 Address
            tmpAddrPtr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
            char addressBuffer[INET_ADDRSTRLEN];
            inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
            if (strcmp(ifa->ifa_name, "lo") != 0) { // exclude loopback interface
                printf("%s IP Address %s
", ifa->ifa_name, addressBuffer);
            }
        } else if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET6) { // check it is IP6
            // is a valid IP6 Address
            tmpAddrPtr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
            char addressBuffer[INET6_ADDRSTRLEN];
            inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
            if (strcmp(ifa->ifa_name, "lo") != 0) { // exclude loopback interface
                printf("%s IP Address %s
", ifa->ifa_name, addressBuffer);
            }
        }
    }
    if (ifAddrStruct != NULL) freeifaddrs(ifAddrStruct);
    return 0;
}

二、使用ioctl和SIOCGIFADDR获取指定网络接口的IP地址

通过ioctl函数和宏常量SIOCGIFADDR可以获取指定网络接口的IP地址,以下是一个示例代码,展示了如何获取名为“eth0”的网络接口的IP地址:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
int main() {
    int sockfd;
    struct ifreq ifr;
    struct sockaddr_in* sin;
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("socket() error");
        return -1;
    }
    strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1);
    if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0) {
        perror("ioctl() error");
        close(sockfd);
        return -1;
    }
    sin = (struct sockaddr_in*)&ifr.ifr_addr;
    printf("IP Address: %s
", inet_ntoa(sin->sin_addr));
    close(sockfd);
    return 0;
}

三、使用gethostname和gethostbyname获取本机IP地址

这种方法首先通过gethostname函数获取主机名,然后通过gethostbyname函数解析主机名以获得IP地址,以下是一个示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main() {
    char hostname[256];
    struct hostent *host;
    struct in_addr **addr_list;
    if (gethostname(hostname, sizeof(hostname)) {
        perror("gethostname");
        return -1;
    }
    host = gethostbyname(hostname);
    if (!host || !host->h_addr_list) {
        perror("gethostbyname");
        return -1;
    }
    printf("IP Address: %s
", inet_ntoa(*host->h_addr_list[0]));
    return 0;
}

四、使用系统命令获取本机IP地址

在Linux系统中,可以通过调用系统命令如hostname -I来获取本机的IP地址,以下是一个示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main() {
    FILE *fp;
    char buffer[128];
    fp = popen("hostname -I", "r");
    if (fp == NULL) {
        perror("popen() error");
        return -1;
    }
    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
        printf("IP Address: %s", buffer);
    }
    pclose(fp);
    return 0;
}

五、使用第三方库(如libpcap)获取本机IP地址

使用第三方库如libpcap可以更方便地获取网络相关信息,以下是一个示例代码,展示如何使用libpcap获取本机IP地址:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pcap.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <net/if.h>
#include <netinet/if_ether.h>
int main() {
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_if_t *alldevs, *d;
    struct sockaddr *sa;
    struct sockaddr_in *sin;
    char *ip_address;
    if (pcap_findalldevs(&alldevs, errbuf) == -1) {
        fprintf(stderr, "Error in pcap_findalldevs: %s
", errbuf);
        return -1;
    }
    for (d = alldevs; d != NULL; d = d->next) {
        sa = d->addresses;
        while (sa != NULL) {
            if (sa->sa_family == AF_INET) { // check it is IP4
                sin = (struct sockaddr_in *)sa;
                ip_address = inet_ntoa(sin->sin_addr);
                printf("Interface: %s, IP Address: %s
", d->name, ip_address);
            } else if (sa->sa_family == AF_INET6) { // check it is IP6
                sin = (struct sockaddr_in6 *)sa;
                ip_address = inet_ntoa(sin->sin6_addr);
                printf("Interface: %s, IP Address: %s
", d->name, ip_address);
            }
            sa = sa->sa_next;
        }
    }
    pcap_freealldevs(alldevs);
    return 0;
}

六、比较不同方法的优劣

方法 优点 缺点
getifaddrs 获取所有网络接口的详细信息,包括IPv4和IPv6地址 需要遍历链表,处理复杂
ioctl 简单直接,适用于指定网络接口 只能获取指定接口的信息
gethostname和gethostbyname 简单直接,跨平台 依赖DNS解析,可能失败
系统命令 实现简单,代码量少 依赖于操作系统命令格式,不具有跨平台性
第三方库(如libpcap) 功能强大,便捷 需要额外安装和配置第三方库

七、FAQs

Q1: 如何在C语言中获取本机IP地址?<br>A1: 可以使用getifaddrs函数、ioctl函数与SIOCGIFADDR宏、gethostname和gethostbyname函数、系统命令以及第三方库如libpcap来获取本机IP地址,具体方法可以参考上述示例代码。

Q2: 如何在C语言中判断IP地址的类型(IPv4还是IPv6)?<br>A2: 可以使用inet_pton函数将IP地址转换为网络地址结构,并通过检查地址族字段来确定IP地址的类型,如果地址族字段等于AF_INET,则表示IPv4地址;如果等于AF_INET6,则表示IPv6地址。

0