ifconfig
或 ip addr show
,可以查看 Linux 系统的本机 IP 地址。在Linux系统下,使用C语言获取本机IP地址是一项非常常见且重要的任务,通过系统调用和相关函数,可以方便地获取并处理网络接口信息,本文将详细介绍几种获取本机IP地址的方法,并提供示例代码、表格以及常见问题的解答。
方法一:使用getifaddrs函数
getifaddrs
函数是获取本机IP地址最常用的方法之一,它能够返回一个包含所有网络接口信息的链表,每个节点包含一个接口的信息,包括IP地址、子网掩码等,以下是详细的步骤和示例代码:
1. 包含必要的头文件
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <ifaddrs.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h>
2. 获取所有网络接口信息
struct ifaddrs *ifAddrStruct = NULL; struct ifaddrs *ifa = NULL; void *tmpAddrPtr = NULL; // 获取所有接口信息 getifaddrs(&ifAddrStruct);
3. 遍历接口信息并提取IPv4地址
for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr == NULL) continue; if (ifa->ifa_addr->sa_family == AF_INET) { // 检查是否为IPv4地址 tmpAddrPtr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; char addressBuffer[INET_ADDRSTRLEN]; inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN); printf("%s IP Address %s ", ifa->ifa_name, addressBuffer); } else if (ifa->ifa_addr->sa_family == AF_INET6) { // 检查是否为IPv6地址 tmpAddrPtr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; char addressBuffer[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN); printf("%s IP Address %s ", ifa->ifa_name, addressBuffer); } }
4. 释放内存
if (ifAddrStruct != NULL) freeifaddrs(ifAddrStruct);
方法二:使用ioctl函数
ioctl
函数可以通过套接字操作来获取网络接口的各种信息,以下是一个使用ioctl
函数获取指定网卡IP地址的示例:
1. 包含必要的头文件
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/ioctl.h> #include <net/if.h> #include <netinet/in.h> #include <arpa/inet.h>
2. 获取指定网卡的IP地址
int get_localip(const char *eth_name, char *local_ip_addr) { int ret = -1; register int fd; struct ifreq ifr; if (local_ip_addr == NULL || eth_name == NULL) { return ret; } if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) > 0) { strcpy(ifr.ifr_name, eth_name); if (!ioctl(fd, SIOCGIFADDR, &ifr)) { ret = 0; strcpy(local_ip_addr, inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr)); } } if (fd > 0) { close(fd); } return ret; }
3. 主函数调用示例
int main() { char local_ip[20] = {0}; int ret = get_localip("eth0", local_ip); if (ret == 0) { printf("Local IP: %s ", local_ip); } else { printf("Failed to get local IP "); } return 0; }
方法三:通过gethostname和gethostbyname函数
这种方法通过主机名获取IP地址,适用于需要根据主机名解析IP的场景。
1. 包含必要的头文件
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/socket.h>
2. 获取主机名并解析IP地址
int main() { char hname[128]; struct hostent *hent; struct in_addr **addr_list; gethostname(hname, sizeof(hname)); hent = gethostbyname(hname); if (hent == NULL) { printf("gethostbyname failed "); return 1; } printf("Host name: %s ", hent->h_name); printf("Address list: "); for (int i = 0; hent->h_addr_list[i] != NULL; i++) { printf("t%s ", inet_ntoa(*(struct in_addr*)(hent->h_addr_list[i]))); } return 0; }
方法 | 优点 | 缺点 |
getifaddrs | 简单易用,支持多接口 | 需要手动排除回环接口 |
ioctl | 灵活,可获取具体网卡信息 | 需要处理套接字和错误 |
gethostname | 根据主机名解析,适用分布式环境 | 依赖DNS解析,可能受网络影响 |
FAQs(常见问题与解答)
Q1: 如何排除回环接口(lo)地址?
A1: 在使用getifaddrs
函数时,可以通过检查接口名称来排除回环接口,可以在遍历接口信息时添加条件判断:strcmp(ifa->ifa_name, "lo") != 0
,这样可以确保只输出非回环接口的IP地址。
Q2: 如果需要获取特定网卡的IP地址,应该如何实现?
A2: 如果需要获取特定网卡的IP地址,可以使用ioctl
函数,通过创建套接字并调用ioctl
函数,传入网卡名称(如"eth0"),即可获取该网卡的IP地址,示例代码如上所示。
小编有话说
在Linux系统下,使用C语言获取本机IP地址是一项非常实用的技能,无论是通过网络编程还是系统管理,掌握这些方法都能让你更好地控制和了解你的系统,希望本文介绍的内容对你有所帮助,如果有任何疑问或建议,欢迎随时留言讨论。
原创文章,作者:未希,如若转载,请注明出处:https://www.kdun.com/ask/1487645.html
本网站发布或转载的文章及图片均来自网络,其原创性以及文中表达的观点和判断不代表本网站。如有问题,请联系客服处理。
发表回复