C 言語で getaddrinfo 関数を使用する
胡金庫
2023年10月12日
この記事では、C 言語で getaddrinfo
関数を使用する方法に関する複数の方法を示します。
C 言語で getaddrinfo
関数を使用して名前を IP アドレスにホストする
getaddrinfo
は UNIX ネットワークプログラミング機能の一部であり、ネットワークホスト情報を IP アドレスに、またはその逆に変換できます。getaddrinfo
も POSIX 準拠の関数呼び出しであり、基盤となるプロトコルに関係なく変換を実行できます。
getaddrinfo
は 4つの引数を取ります。
- 1つ目は、ホスト名または IPv4 / IPv6 形式のアドレス文字列へのポインタにすることができます。
- 2 番目の引数は、サービス名または 10 進整数で表されるポート番号にすることができます。
- 次の 2つの引数は、
addrinfo
構造体へのポインターです。1つ目は、取得したソケット構造をフィルタリングするための要件を指定するhints
であり、2つ目は、関数がaddrinfo
構造体のリンクリストを動的に割り当てるポインタです。
hints
構造体はゼロで設定してから、そのメンバーを割り当てる必要があることに注意してください。ai_family
メンバーは、アドレスファミリを示します。たとえば、IPv4 または IPv6 は、それぞれ AF_INET および AF_INET6 として示されます。この場合、サービス名の変換には関心がなく、関数の 2 番目の引数として 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
C 言語で getnameinfo
関数を使用して IP アドレスをホスト名に変換する
この場合、getnameinfo
関数は getaddrinfo
と組み合わせて使用され、対応する IP アドレスのホスト名を取得します。最初のコマンドライン引数からのユーザー入力を処理し、それを getaddrinfo
引数として渡して、socketaddr
構造体を取得することに注意してください。最後に、各構造をホスト名文字列に変換できます。getaddrinfo
は 4 番目の引数にリンクリストを格納するために動的メモリを割り当てるため、このポインタは 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
著者: 胡金庫