获取本机 IP 地址有多种方法,下面介绍两种常见的方法。
方法一:使用 getifaddrs 函数
getifaddrs 函数可以获取系统中所有网络接口的信息,包括接口名称、IP 地址等。我们可以遍历这个链表,找到具有有效 IP 地址的网络接口,并取出它的 IP 地址。
示例代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <ifaddrs.h>
int main() {
struct ifaddrs *addrs, *addr;
void *tmp_addr;
char ip_str[INET_ADDRSTRLEN];
// 获取所有网络接口信息
if (getifaddrs(&addrs) == -1) {
perror("getifaddrs");
exit(EXIT_FAILURE);
}
// 遍历链表查找有效 IP 地址
for (addr = addrs; addr != NULL; addr = addr->ifa_next) {
// 忽略非 IPv4 接口和无效地址
if (addr->ifa_addr == NULL || addr->ifa_addr->sa_family != AF_INET)
continue;
tmp_addr = &((struct sockaddr_in*)addr->ifa_addr)->sin_addr;
inet_ntop(AF_INET, tmp_addr, ip_str, INET_ADDRSTRLEN);
printf("%s: %s\n", addr->ifa_name, ip_str);
}
freeifaddrs(addrs);
return 0;
}
运行结果如下:
lo: 127.0.0.1
eth0: 192.168.1.100
在这个示例程序中,我们首先使用 getifaddrs 函数获取系统中所有网络接口的信息,并遍历链表查找有效 IP 地址。在遍历过程中,我们忽略了非 IPv4 接口和无效地址。对于每个有效地址,我们将其转换为点分十进制格式,并打印出来。
方法二:使用 ioctl 和 SIOCGIFADDR 命令
ioctl 函数可以用来操作设备驱动程序,在 Linux 中,它也可以用于获取或设置网络接口的信息。SIOCGIFADDR 是一个 ioctl 命令,它用于获取指定接口的 IP 地址。
示例代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
int main() {
int sockfd;
struct ifreq ifr;
char ip_str[INET_ADDRSTRLEN];
// 创建 socket 文件描述符
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
// 设置要查询的网络接口名称
strcpy(ifr.ifr_name, "eth0");
// 发送 SIOCGIFADDR 命令以获取 IP 地址
if (ioctl(sockfd, SIOCGIFADDR, &ifr) == -1) {
perror("ioctl");
close(sockfd);
exit(EXIT_FAILURE);
}
// 将二进制地址转换为点分十进制格式
inet_ntop(AF_INET, &((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr, ip_str, INET_ADDRSTRLEN);
printf("IP address: %s\n", ip_str);
close(sockfd);
return 0;
}
运行结果如下:
IP address: 192.168.1.100
在这个示例程序中,我们首先创建一个 socket 文件描述符,并设置要查询的网络接口名称。然后,使用 ioctl 函数发送 SIOCGIFADDR 命令以获取 IP 地址。最后,将返回的二进制地址转换为点分十进制格式,并打印出来。
需要注意的是,上述代码中硬编码了网络接口名称 “eth0”,在实际应用中应该根据具体情况修改为正确的接口名称。