Linux C语言如何获取IP地址?

99ANYc3cd6
预计阅读时长 16 分钟
位置: 首页 C语言 正文

在 Linux C 语言中获取本机 IP 地址,通常需要结合使用套接字(Socket)和系统调用(如 getifaddrs)来获取网络接口信息,以下是几种常见的方法:

linux c语言获取ip
(图片来源网络,侵删)

方法 1:使用 getifaddrs(推荐)

getifaddrs 是 POSIX 标准函数,可以获取所有网络接口的详细信息(包括 IP 地址)。

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void print_ip_addresses() {
    struct ifaddrs *ifaddrs_ptr = NULL;
    struct ifaddrs *ifa = NULL;
    if (getifaddrs(&ifaddrs_ptr) == -1) {
        perror("getifaddrs failed");
        return;
    }
    for (ifa = ifaddrs_ptr; ifa != NULL; ifa = ifa->ifa_next) {
        if (ifa->ifa_addr == NULL) continue;
        // 检查是否是 IPv4 地址
        if (ifa->ifa_addr->sa_family == AF_INET) {
            struct sockaddr_in* addr_in = (struct sockaddr_in*)ifa->ifa_addr;
            char ip_str[INET_ADDRSTRLEN];
            inet_ntop(AF_INET, &(addr_in->sin_addr), ip_str, INET_ADDRSTRLEN);
            printf("Interface: %-8s | IPv4 Address: %s\n", ifa->ifa_name, ip_str);
        }
        // 检查是否是 IPv6 地址(可选)
        else if (ifa->ifa_addr->sa_family == AF_INET6) {
            struct sockaddr_in6* addr_in6 = (struct sockaddr_in6*)ifa->ifa_addr;
            char ip_str[INET6_ADDRSTRLEN];
            inet_ntop(AF_INET6, &(addr_in6->sin6_addr), ip_str, INET6_ADDRSTRLEN);
            printf("Interface: %-8s | IPv6 Address: %s\n", ifa->ifa_name, ip_str);
        }
    }
    freeifaddrs(ifaddrs_ptr);
}
int main() {
    printf("Local IP Addresses:\n");
    print_ip_addresses();
    return 0;
}

编译与运行:

gcc get_ip.c -o get_ip
./get_ip

输出示例:

Local IP Addresses:
Interface: lo      | IPv4 Address: 127.0.0.1
Interface: eth0    | IPv4 Address: 192.168.1.100
Interface: wlan0   | IPv4 Address: 10.0.0.5

方法 2:使用 ioctlSIOCGIFADDR

通过 ioctl 系统调用直接查询指定接口的 IP 地址(仅适用于 IPv4)。

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void get_interface_ip(const char *interface) {
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("socket creation failed");
        return;
    }
    struct ifreq ifr;
    strncpy(ifr.ifr_name, interface, IFNAMSIZ - 1);
    if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0) {
        perror("ioctl failed");
        close(sockfd);
        return;
    }
    struct sockaddr_in *addr = (struct sockaddr_in *)&ifr.ifr_addr;
    char ip_str[INET_ADDRSTRLEN];
    inet_ntop(AF_INET, &(addr->sin_addr), ip_str, INET_ADDRSTRLEN);
    printf("Interface: %-8s | IPv4 Address: %s\n", interface, ip_str);
    close(sockfd);
}
int main() {
    printf("IP Addresses for specific interfaces:\n");
    get_interface_ip("eth0");
    get_interface_ip("lo");
    return 0;
}

编译与运行:

gcc ioctl_ip.c -o ioctl_ip
./ioctl_ip

方法 3:解析 /proc/net/dev(仅限 Linux)

直接读取 /proc/net/dev 文件解析 IP 地址(需要额外解析 /proc/net/fib_trie 或使用其他工具)。

示例代码(简化版):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void parse_proc_net_dev() {
    FILE *fp = fopen("/proc/net/dev", "r");
    if (!fp) {
        perror("Failed to open /proc/net/dev");
        return;
    }
    char line[256];
    while (fgets(line, sizeof(line), fp)) {
        if (strstr(line, ":")) {
            char *interface = strtok(line, ":");
            printf("Interface: %s\n", interface);
        }
    }
    fclose(fp);
}
int main() {
    parse_proc_net_dev();
    return 0;
}

注意事项:

  1. 权限问题:某些操作可能需要 root 权限(如访问网络设备)。
  2. 接口筛选:实际使用时可能需要过滤回环接口(lo)或无效接口。
  3. IPv6 支持:如需 IPv6 地址,需检查 AF_INET6 并使用 inet_ntop
  4. 错误处理:始终检查函数返回值(如 getifaddrsioctl)。

  • 推荐方法:使用 getifaddrs(通用、简单、支持 IPv4/IPv6)。
  • 传统方法ioctl 适用于特定接口查询。
  • 文件解析:适用于简单场景,但不够健壮。

选择适合你需求的方法即可!

linux c语言获取ip
(图片来源网络,侵删)
linux c语言获取ip
(图片来源网络,侵删)
-- 展开阅读全文 --
头像
dede在线留言如何调用?
« 上一篇 今天
dede根目录调用标签
下一篇 » 今天

相关文章

取消
微信二维码
支付宝二维码

目录[+]