在 C 語言中使用 getaddrinfo 函式
    
    Jinku Hu
    2023年10月12日
    
    C
    C Networking
    
 
本文將演示有關如何在 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
        Enjoying our tutorials? Subscribe to DelftStack on YouTube to support us in creating more high-quality video guides. Subscribe
    
作者: Jinku Hu
    
