在 C 語言中使用 getaddrinfo 函式
Jinku Hu
2023年10月12日
本文將演示有關如何在 C 語言中使用 getaddrinfo
函式的多種方法。
在 C 語言中使用 getaddrinfo
函式將主機名轉換為 IP 地址
getaddrinfo
是 UNIX 網路程式設計工具的一部分,它可以將網路主機資訊轉換為 IP 地址,反之亦然。getaddrinfo
也是 POSIX 相容的函式呼叫,無論底層協議如何,它都可以進行轉換。
getaddrinfo
接受四個引數,
- 第一個可以是指向主機名或 IPv4/IPv6 格式的地址字串的指標。
- 第二個引數可以是服務名稱或用十進位制整數表示的埠號。
- 接下來的兩個引數是指向
addrinfo
結構的指標。第一個是hints
,它指定過濾檢索到的套接字結構的要求,而第二個是指標,該函式將動態分配addrinfo
結構的連結串列。
注意,hints
結構體應設定為零,然後為其分配成員。ai_family
成員將地址族(例如 IPv4 或 IPv6)分別表示為 AF_INET 和 AF_INET6。在這種情況下,我們對服務名轉換不感興趣,並指定 NULL
作為該函式的第二個引數。最後,我們呼叫 getnameinfo
將給定的 sockaddr
結構轉換為可列印形式。
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
int main(int argc, char const *argv[]) {
struct addrinfo hints;
struct addrinfo *res, *tmp;
char host[256];
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
if (argc != 2) {
fprintf(stderr, "%s string\n", argv[0]);
exit(EXIT_FAILURE);
}
int ret = getaddrinfo(argv[1], NULL, &hints, &res);
if (ret != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret));
exit(EXIT_FAILURE);
}
for (tmp = res; tmp != NULL; tmp = tmp->ai_next) {
getnameinfo(tmp->ai_addr, tmp->ai_addrlen, host, sizeof(host), NULL, 0,
NI_NUMERICHOST);
puts(host);
}
freeaddrinfo(res);
exit(EXIT_SUCCESS);
}
示例命令:
./program localhost
輸出:
127.0.0.1
127.0.0.1
127.0.0.1
使用 getnameinfo
函式將 IP 地址轉換為 C 語言中的主機名
在這種情況下,getnameinfo
函式與 getaddrinfo
一起使用,它檢索對應 IP 地址的主機名。注意,我們處理了第一個命令列引數的使用者輸入,並將其作為 getaddrinfo
引數傳遞,以檢索 socketaddr
結構。最後,每個結構都可以轉換為主機名字串。由於 getaddrinfo
分配動態記憶體以將連結列表儲存在第四個引數中,因此使用者應通過 freeaddrinfo
函式呼叫來釋放此指標。
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
int main(int argc, char const *argv[]) {
struct addrinfo hints;
struct addrinfo *res, *tmp;
char host[256];
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
if (argc != 2) {
fprintf(stderr, "%s string\n", argv[0]);
exit(EXIT_FAILURE);
}
int ret = getaddrinfo(argv[1], NULL, &hints, &res);
if (ret != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret));
exit(EXIT_FAILURE);
}
for (tmp = res; tmp != NULL; tmp = tmp->ai_next) {
getnameinfo(tmp->ai_addr, tmp->ai_addrlen, host, sizeof(host), NULL, 0, 0);
}
freeaddrinfo(res);
exit(EXIT_SUCCESS);
}
示例命令:
./program 127.0.0.1
輸出:
localhost
localhost
localhost
作者: Jinku Hu