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

(图片来源网络,侵删)
方法 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:使用 ioctl 和 SIOCGIFADDR
通过 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;
}
注意事项:
- 权限问题:某些操作可能需要
root权限(如访问网络设备)。 - 接口筛选:实际使用时可能需要过滤回环接口(
lo)或无效接口。 - IPv6 支持:如需 IPv6 地址,需检查
AF_INET6并使用inet_ntop。 - 错误处理:始终检查函数返回值(如
getifaddrs、ioctl)。
- 推荐方法:使用
getifaddrs(通用、简单、支持 IPv4/IPv6)。 - 传统方法:
ioctl适用于特定接口查询。 - 文件解析:适用于简单场景,但不够健壮。
选择适合你需求的方法即可!

(图片来源网络,侵删)

(图片来源网络,侵删)
