0.概要
本文介绍用C语言编写一个函数来获取本机的IP地址。
1. 设计
将获取IP地址的逻辑封装到一个独立的函数中,并定义一个结构体来存储IP地址和接口名称。
将获取IP地址的逻辑封装到一个函数中,该函数遍历本机的所有网络接口并获取其IP地址.
2. 完整的代码
完整的代码如下:
ip_address.h
#ifndef IP_ADDRESS_H
#define IP_ADDRESS_H
#include <netinet/in.h>
#include <net/if.h>
#define MAX_IP_ADDRESSES 50
#define INET6_ADDRSTRLEN 46
typedef struct {
char ifa_name[IFNAMSIZ];
char ip_address[INET6_ADDRSTRLEN];
int family;
} IPAddress;
int get_ip_addresses(IPAddress *ip_addresses, int max_addresses);
#endif // IP_ADDRESS_H
ip_address.c
#include "ip_address.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
int get_ip_addresses(IPAddress *ip_addresses, int max_addresses) {
struct ifaddrs *ifAddrStruct = NULL;
struct ifaddrs *ifa = NULL;
void *tmpAddrPtr = NULL;
int count = 0;
if (getifaddrs(&ifAddrStruct) == -1) {
/* Error handling */
return -1;
}
for (ifa = ifAddrStruct; ifa != NULL && count < max_addresses; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL) {
continue;
}
int family = ifa->ifa_addr->sa_family;
if (family == AF_INET) {
tmpAddrPtr = &((struct sockaddr_in *)(ifa->ifa_addr))->sin_addr;
if (inet_ntop(AF_INET, tmpAddrPtr, ip_addresses[count].ip_address, INET_ADDRSTRLEN) != NULL) {
strncpy(ip_addresses[count].ifa_name, ifa->ifa_name, IFNAMSIZ);
ip_addresses[count].family = AF_INET;
count++;
}
} else if (family == AF_INET6) {
tmpAddrPtr = &((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_addr;
if (inet_ntop(AF_INET6, tmpAddrPtr, ip_addresses[count].ip_address, INET6_ADDRSTRLEN) != NULL) {
strncpy(ip_addresses[count].ifa_name, ifa->ifa_name, IFNAMSIZ);
ip_addresses[count].family = AF_INET6;
count++;
}
} else {
/* Do nothing */
}
}
freeifaddrs(ifAddrStruct);
return count;
}
main.c
#include <stdio.h>
#include "ip_address.h"
int main(void) {
IPAddress ip_addresses[MAX_IP_ADDRESSES];
int count = get_ip_addresses(ip_addresses, MAX_IP_ADDRESSES);
if (count == -1) {
fprintf(stderr, "Failed to get IP addresses.\n");
return 1;
}
for (int i = 0; i < count; i++) {
if (ip_addresses[i].family == AF_INET) {
printf("%s IPv4 Address: %s\n", ip_addresses[i].ifa_name, ip_addresses[i].ip_address);
} else if (ip_addresses[i].family == AF_INET6) {
printf("%s IPv6 Address: %s\n", ip_addresses[i].ifa_name, ip_addresses[i].ip_address);
}
}
return 0;
}
编译命令
gcc -o ip_address main.c ip_address.c
执行结果
test@t:~/ip_address$ ./ip_address
lo IPv4 Address: 127.0.0.1
ens33 IPv4 Address: 192.168.1.10
lo IPv6 Address: ::1
ens33 IPv6 Address: 2409:8a20:4e3c:d460:20c:29ff:feb3:d386
ens33 IPv6 Address: fe80::20c:29ff:feb3:d386
通过上述步骤,你将能够获取并打印本机的所有IPv4和IPv6地址。