在 C 語言中使用 getaddrinfo 函式

Jinku Hu 2023年1月30日 2021年3月21日
  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 <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.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 <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.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
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相關文章 - C Networking