Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學

Linux C 語言獲取本機 IP 位址:ioctl + SIOCGIFADDR 實作範例

編輯:Linux 系統常見問題解答

核心思路

建立一個 UDP Socket,透過 ioctl 系統呼叫搭配 SIOCGIFADDR 指令,從核心查詢指定網卡(如 eth0)的 IPv4 位址結構 sockaddr_in,再用 inet_ntoa 轉為點分十進制字串。

完整程式碼

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>

#define ETH_NAME "eth0"

int main(void) {
    int sock;
    struct sockaddr_in sin;
    struct ifreq ifr;

    sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock == -1) {
        perror("socket");
        return -1;
    }

    strncpy(ifr.ifr_name, ETH_NAME, IFNAMSIZ);
    ifr.ifr_name[IFNAMSIZ - 1] = '\0';

    if (ioctl(sock, SIOCGIFADDR, &ifr) < 0) {
        perror("ioctl");
        close(sock);
        return -1;
    }

    memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
    printf("%s: %s\n", ETH_NAME, inet_ntoa(sin.sin_addr));

    close(sock);
    return 0;
}

編譯與執行

gcc get_ip.c -o get_ip
./get_ip
# 輸出範例:eth0: 192.168.1.100

關鍵點解析

  • SOCK_DGRAM:UDP Socket 即可,無需建立連線。
  • struct ifreq:網卡請求結構,ifr_name 指定介面名,ifr_addr 回傳地址。
  • SIOCGIFADDR:取得介面 IPv4 位址的 ioctl 指令碼。
  • inet_ntoa:將網路序 in_addr 轉為字串(注意:非執行緒安全,現代代碼建議用 inet_ntop)。

擴展:獲取所有介面 IP

使用 getifaddrs()(<ifaddrs.h>)遍歷鏈表,可一次取得所有網卡的 IPv4/IPv6 位址,更適合現代應用。

總結

透過 ioctl + SIOCGIFADDR 是 Linux C 程式獲取指定網卡 IP 的經典做法,理解其結構體佈局與核心交互機制,有助於深入掌握 Linux 網路程式設計。

Copyright © Windows教程網 All Rights Reserved