在 C 語言中使用 getaddrinfo 函式

Jinku Hu 2023年10月12日
  1. 在 C 語言中使用 getaddrinfo 函式將主機名轉換為 IP 地址
  2. 使用 getnameinfo 函式將 IP 地址轉換為 C 語言中的主機名
在 C 語言中使用 getaddrinfo 函式

本文將演示有關如何在 C 語言中使用 getaddrinfo 函式的多種方法。

在 C 語言中使用 getaddrinfo 函式將主機名轉換為 IP 地址

getaddrinfo 是 UNIX 網路程式設計工具的一部分,它可以將網路主機資訊轉換為 IP 地址,反之亦然。getaddrinfo 也是 POSIX 相容的函式呼叫,無論底層協議如何,它都可以進行轉換。

getaddrinfo 接受四個引數,

  1. 第一個可以是指向主機名或 IPv4/IPv6 格式的地址字串的指標。
  2. 第二個引數可以是服務名稱或用十進位制整數表示的埠號。
  3. 接下來的兩個引數是指向 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
Jinku Hu avatar Jinku Hu avatar

DelftStack.com 創辦人。Jinku 在機器人和汽車行業工作了8多年。他在自動測試、遠端測試及從耐久性測試中創建報告時磨練了自己的程式設計技能。他擁有電氣/ 電子工程背景,但他也擴展了自己的興趣到嵌入式電子、嵌入式程式設計以及前端和後端程式設計。

LinkedIn Facebook

相關文章 - C Networking