首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Linux 獲取指定網卡 IPv4 地址:基於 getifaddrs 的跨平台實現

     編輯:關於C語言

問題背景

常見 gethostname + gethostbyname 組合往往返回 127.0.0.1 或非預期介面 IP。需精確綁定指定網卡(如 eth0、ens33)的局域網 IPv4 地址。

核心方案:getifaddrs 遍歷介面

#include 
#include 
#include 
#include 

const char* get_interface_ipv4(const char *iface_name) {
    struct ifaddrs *ifaddr, *ifa;
    static char ip_str[INET_ADDRSTRLEN];  // 靜態緩衝區,線程不安全

    if (getifaddrs(&ifaddr) == -1) return NULL;

    for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
        if (!ifa->ifa_addr) continue;
        if (ifa->ifa_addr->sa_family != AF_INET) continue;  // 僅 IPv4
        if (strcmp(ifa->ifa_name, iface_name) != 0) continue;

        struct sockaddr_in *sa = (struct sockaddr_in*)ifa->ifa_addr;
        inet_ntop(AF_INET, &sa->sin_addr, ip_str, INET_ADDRSTRLEN);
        freeifaddrs(ifaddr);
        return ip_str;
    }
    freeifaddrs(ifaddr);
    return NULL;
}

關鍵點解析

  • getifaddrs 獲取鏈表,需配對 freeifaddrs 釋放。
  • ifa_addr->sa_family == AF_INET 過濾 IPv4(排除 IPv6/AF_PACKET 等)。
  • inet_ntop 線程安全替代 inet_ntoa,支援 IPv6 擴展。
  • 返回靜態緩衝區指針,多線程環境建議改為呼叫者提供緩衝區。

完整可執行範例

#include 
#include 
#include 
#include 
#include 

int main(int argc, char *argv[]) {
    if (argc < 2) {
        fprintf(stderr, "Usage: %s \n", argv[0]);
        return 1;
    }
    const char *ip = get_interface_ipv4(argv[1]);
    if (ip) printf("Interface %s IPv4: %s\n", argv[1], ip);
    else fprintf(stderr, "Interface not found or no IPv4 address\n");
    return 0;
}

編譯與測試

gcc -o get_ip get_ip.c
./get_ip eth0
# 輸出:Interface eth0 IPv4: 192.168.1.100

常見坑點與替代方案

總結

getifaddrs 是 POSIX 標準、跨平台(Linux/macOS/*BSD)獲取介面地址的推薦方式。結合 AF_INET 過濾與介面名匹配,可精確獲取目標網卡 IPv4 地址,避開回環地址干擾。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
場景問題對策
多 IP 別名eth0:1 視為獨立介面精確匹配 ifa_name 或遍歷所有同前綴介面
容器/虛擬網卡介面名不固定配合 ip route get 8.8.8.8 解析出口介面
無權限需 root 讀取 /proc/netgetifaddrs 通常無需特權
Windows 移植無 getifaddrs使用 GetAdaptersAddresses (IPHLPAPI)