📅  最后修改于: 2023-12-03 15:09:58.191000             🧑  作者: Mango
在现代互联网时代,IP 地址已经成为计算机网络中不可或缺的部分。在这里,我们将介绍如何用 C 编程语言获取当前计算机的 IP 地址。
C 语言中,可以使用 getaddrinfo
函数来获取 IP 地址。该函数可以支持 IPv4 和 IPv6 地址类型,并且可以选择返回所需协议类型的地址信息。下面是一个使用 getaddrinfo
函数获取 IP 地址的简单例子:
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
struct addrinfo hints, *res, *p;
int status;
char ipstr[INET6_ADDRSTRLEN];
if (argc < 2) {
fprintf(stderr, "usage: %s hostname\n", argv[0]);
return 1;
}
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
hints.ai_socktype = SOCK_STREAM;
if ((status = getaddrinfo(argv[1], NULL, &hints, &res)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
return 2;
}
printf("IP addresses for %s:\n\n", argv[1]);
for (p = res; p != NULL; p = p->ai_next) {
// convert address to IPv4 or IPv6 string
void *addr;
char *ipver;
if (p->ai_family == AF_INET) { // IPv4
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
addr = &(ipv4->sin_addr);
ipver = "IPv4";
} else { // IPv6
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
addr = &(ipv6->sin6_addr);
ipver = "IPv6";
}
// convert the IP to a string and print it:
inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
printf(" %s: %s\n", ipver, ipstr);
}
freeaddrinfo(res); // free the linked list
return 0;
}
在该例子中,我们首先定义了一个 addrinfo
的结构体变量 hints
,并赋值了需要获取的地址类型为 AF_UNSPEC
,即既可以获取 IPv4 地址,也可以获取 IPv6 地址。然后使用 getaddrinfo
函数来获取目标主机名对应的地址信息,并将结果存放在 res
指针所指的 addrinfo
结构体链表中。最后使用 inet_ntop
函数将 struct sockaddr
结构体类型的 IP 地址转化为字符串,便于输出。
下面是示例代码片段,用于获取本地主机的 IP 地址:
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <arpa/inet.h>
void getmyip(char *ipstr, int len)
{
char hostname[256];
struct addrinfo hints, *res, *p;
int status;
// get hostname
if (gethostname(hostname, sizeof(hostname)) < 0) {
perror("gethostname");
return;
}
// get address info
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((status = getaddrinfo(hostname, NULL, &hints, &res)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
return;
}
// loop through all the results and get the IP address
for (p = res; p != NULL; p = p->ai_next) {
void *addr;
char *ipver;
if (p->ai_family == AF_INET) { // IPv4
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
addr = &(ipv4->sin_addr);
ipver = "IPv4";
} else { // IPv6
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
addr = &(ipv6->sin6_addr);
ipver = "IPv6";
}
// convert the IP to a string and copy it to the result buffer
inet_ntop(p->ai_family, addr, ipstr, len);
break; // only need first IP address
}
freeaddrinfo(res);
}
使用该代码片段,可以调用 getmyip
函数来获取本地主机的 IP 地址,并将结果存储在 ipstr
变量中。如果调用成功,函数将返回 0,否则将返回 -1。下面是一个使用该函数的例子:
#include <stdio.h>
int main()
{
char ipstr[INET6_ADDRSTRLEN];
if (getmyip(ipstr, sizeof(ipstr)) == 0) {
printf("My IP address is: %s\n", ipstr);
} else {
fprintf(stderr, "Error: unable to get IP address.\n");
return 1;
}
return 0;
}
在该例子中,我们调用 getmyip
函数来获取本地主机的 IP 地址,并将结果输出到标准输出流中。如果获取成功,将输出类似于 My IP address is: 192.168.1.100
的信息,否则将输出错误信息并退出程序。