`

主机名与 IP 地址的转换(续)

阅读更多
        在主机名与 IP 地址的转换一节中提到的 gethostbyname 和 gethostbyaddr 函数仅仅支持 IPv4,本节将介绍一个同时支持 IPv4 和 IPv6 的 getaddrinfo 函数,它能够处理名字到地址以及服务到端口这两种转换。
#include <netdb.h>
int getaddrinfo(const char *hostname, const char *service, 
                const struct addrinfo *hints, struct addrinfo **result);
                                      /* 返回值:若成功返回 0,否则返回非 0 */
const char *gai_strerror(int error);  /* 返回:指向错误描述消息的指针 */
void freeaddrinfo(struct addrinfo *ai);

struct addrinfo{
    int            ai_flags;           // AI_PASSIVE, AI_CANONNAME
    int            ai_family;          // AF_xxx
    int            ai_socktype;        // SOCK_xxx
    int            ai_protocol;        // 0 or IPPROTO_xxx for IPv4 and IPv6
    socklen_t      ai_addrlen;         // length of ai_addr
    char          *ai_canonname;       // ptr to canonical name for host
    struct sockaddr    *ai_addr;       // ptr to socket address structure
    struct addrinfo    *ai_next;       // ptr to next structure in linked list
};

        其中,hostname 参数是一个主机名,也可以是一个 IPv4 点分十进制或者 IPv6 十六进制数串。service 参数是一个服务名或十进制端口号数串。函数最终通过 result 参数返回一个指向 addrinfo 结构链表的指针,该链表是由 getaddrinfo 函数动态分配的,之后各个 addrinfo 结构中的 ai_addr 成员就可直接用于后续的 socket 等函数中。
        hints 参数可以是一个空指针,也可以是一个指向某个 addrinfo 结构的指针,调用者可以在该结构中填入关于期望返回的信息类型的暗示。比如,如果指定的服务既支持 TCP 也支持 UDP,则可以把该结构中的 ai_socktype 成员设置为 SOCK_DGRAM,使得返回的仅仅是适用于数据报套接字的信息。
        hints 结构中调用者可以设置的成员有:
        * ai_flags(零个或多个 AI_xxx 值的并集)
        * ai_family(某个 AF_xxx 值)
        * ai_socktype(某个 SOCK_xxx 值)
        * ai_protocol
        其中 ai_flags 成员可用的标志值及其含义如下。
        1、AI_PASSIVE:套接字将用于被动打开。
        2、AI_CANONNAME:告知 getaddrinfo 函数返回主机的规范名字,此时该函数返回的第一个 addrinfo 结构的 ai_canonname 成员就指向所查找主机的规范名字。
        3、AI_NUMERICHOST:只允许 hostname 参数是一个地址数串。
        4、AI_NUMERICSERV:只允许 service 参数是一个十进制数串。
        5、AI_V4MAPPED:如果同时指定 ai_family 成员的值为 AF_INET6,那么当没有可用的 AAAA 记录时就返回与 A 记录对应的 IPv4 映射的 IPv6 地址。
        6、AI_ALL:如果同时指定 AI_V4MAPPED 标志,则除了返回与 AAAA 记录对应的 IPv6 地址外,还返回与 A 记录对应的 IPv4 映射的 IPv6 地址。
        7、AI_ADDRCONFIG:按照所在主机的配置选择返回地址类型,也就是只查找与所在主机回馈接口以外的网络接口配置的 IP 地址版本一致的地址。
        如果 hints 参数是一个空指针,本函数就假设 ai_flags、ai_socktype 和 ai_protocol 的值均为 0,而 ai_family 的值为 AF_UNSPEC。
        为便于理解,假设有台主机 freebsd4 的规范名字是“freebsd4.unpbook.com”,并且它在 DNS(服务名是 domain,端口是 53)中有 2 个 IPv4 地址,那么在执行了如下的程序片段后:
struct addrinfo    hints, *res;
zero(&hints, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_INET;
getaddrinfo("freebsd4", "domain", &hints, &res);

        res 变量将指向一个由 getaddrinfo 函数动态分配的 addrinfo 结构链表,如下图所示。

        getaddrinfo 函数出错时会返回非 0 错误值,可利用 gai_strerror 函数来获取对应的描述信息。下表总结了这些错误值的名字和含义。

        getaddrinfo 返回的所有存储空间都是动态分配的,这些空间可使用 freeaddrinfo 函数释放,它的 ai 参数应指向由 getaddrinfo 函数返回的第一个 addrinfo 结构,因此在调用 freeaddrinfo 函数后,就一定不能再使用这些空间中保存的数据。

        和 getaddrinfo 函数相对应的是 getnameinfo 函数,它以一个套接字地址结构作为参数,返回描述其中的主机的一个字符串和描述其中的服务的另一个字符串。它也是协议无关的。
#include <netdb.h>
int getnameinfo(const struct sockaddr *sockaddr, socklen_t addrlen,
                char *host, socklen_t hostlen,
                char *serv, socklen_t servlen, int flags);
                        /* 返回值:若成功则为 0,否则为非 0(同 getaddrinfo) */

        这里,sockaddr 参数指向包含待转换的协议地址结构,addrlen 是该结构的长度。host 参数和 serv 参数可分别代表用来存储返回的主机和服务字符串,它们都需要由调用者预先分配存储空间。如果不想返回主机或服务字符串,可将 hostlen 或 servlen 参数指定为 0。
        flags 参数可以用于改变 getnameinfo 的操作,可指定的值及其说明如下图所示。

        在此需要注意的是,当调用者知道要处理的是数据报套接字时,应设置 NI_DGRAM 标志,因为套接字地址结构中仅给出了 IP 地址和端口号,getnameinfo 无法就此确定所用的协议。
  • 大小: 88.6 KB
  • 大小: 27.4 KB
  • 大小: 18.2 KB
分享到:
评论

相关推荐

    IP地址与主机名相互转换解析

    // 使用gethostbyaddr将IP转换为主机名 struct in_addr addr; inet_aton("192.168.1.1", &addr); host_entry = gethostbyaddr((const void *)&addr, sizeof(addr), AF_INET); if (host_entry == NULL) { ...

    易语言将指定的主机名与IP地址转换功能

    在编程领域,网络通信是不可或缺的一部分,而主机名与IP地址之间的转换是网络通信中的基础操作。易语言作为一款中国本土开发的、面向初学者的编程语言,也提供了相应的功能来实现这一转换。本篇文章将深入讲解如何...

    IP地址和主机名的转换程序 C#

    10. **项目结构**:一个简单的IP地址与主机名转换程序可能包括一个主函数,调用`Dns.GetHostEntry`或`Dns.Resolve`方法,然后显示或存储转换结果。用户界面可能是命令行形式或者图形用户界面(GUI),如Windows ...

    C++编程系列之获得主机名和IP地址

    这段代码首先获取主机名,然后使用`getaddrinfo`函数查找与之相关的IP地址。`getaddrinfo`返回一个链表,包含了不同类型的IP地址。遍历这个链表,使用`inet_ntop`函数将二进制的IP地址转换为人类可读的形式。 需要...

    利用Asp.net获取主机名和IP地址

    `AddressList`属性是一个`IPAddress`对象数组,包含了与主机名关联的所有IP地址,包括IPv4和IPv6。 在实际应用中,我们可能只需要IPv4或IPv6地址,可以进行筛选: ```csharp IPAddress ipv4Address = null; ...

    获取主机名和IP地址

    1. **DNS解析**:DNS(Domain Name System)是将主机名转换为IP地址的服务。在程序中,我们可以使用DNS查询来获取IP地址。在Python中,可以使用`socket.gethostbyname()`函数实现,如`ip_address = socket....

    用MFC如何获取本地主机名和IP地址

    获取本地主机名和IP地址的MFC实现 在MFC应用程序中,获取本地主机名和IP地址是一项基本的网络编程任务。下面,我们将介绍如何使用MFC框架来实现这个功能。 首先,我们需要在StdAfx.h文件中包含afxsock.h头文件,...

    通过IP批量获取主机名

    3. **进行DNS解析**:对于每一行IP,使用编程语言提供的DNS库或函数(如Python的`socket.gethostbyaddr()`)进行反向解析,将IP转换为主机名。这个函数会返回一个包含主机名、域名和IP地址列表的元组,通常我们只...

    通过IP地址获取主机名

    在IT行业中,网络通信是不可或缺的一部分,而网络通信的基础之一就是IP地址与主机名的相互转换。本篇文章将深入探讨如何在Delphi 2009环境下编写一个小程序,实现通过IP地址获取主机名的功能。 首先,让我们了解IP...

    调用Winsock中函数编程获取本机的主机名和IP地址.

    在Windows系统中,如果你需要通过编程方式获取本机的主机名和IP地址,可以使用Winsock库中的函数。Winsock是Windows Socket接口的简称,它为应用程序提供了标准的网络通信功能。下面我们将详细讨论如何利用Winsock库...

    自动获取主机名和IP

    如果需要将主机名转换为IP地址,可以使用`gethostbyname`函数。这个函数接收主机名作为参数,返回一个`hostent`结构体,其中包含了IP地址等信息。结构体中的`h_addr_list`成员包含了IP地址列表。注意,对于IPv4,...

    通过IP获取主机的名字

    在IT领域,网络通信是不可或缺的一部分,而主机名与IP地址之间的转换是网络通信中的基本操作。本篇文章将深入探讨如何在Unix/Linux环境下,利用C语言通过IP地址获取主机名的相关知识点。 首先,我们需要理解IP地址...

    MFC获取主机名,IP地址,MAC地址

    在这个主题中,“MFC获取主机名,IP地址,MAC地址”指的是如何在MFC应用中获取计算机的相关网络信息。 首先,获取主机名是通过Windows API函数`GetComputerName`来完成的。这个函数允许程序获取当前系统的计算机名...

    获取本机主机名和IP地址

    在IT领域,获取本机主机名和IP地址是常见的网络编程任务,这涉及到操作系统与网络接口的交互。本文将详细讲解这两个概念以及如何在不同环境下实现获取。 首先,主机名是一个标识符,用于唯一地识别网络上的计算机。...

    转换IP地址为主机名的控件

    标题 "转换IP地址为主机名的控件" 描述了这样一个功能:将数字形式的IP地址转换成人类可读的主机名。在计算机网络中,IP地址是标识网络上设备的唯一数字序列,而主机名则是一种便于记忆的字符串形式。这个控件可能是...

    Delphi通过IP获取主机名

    - Delphi提供了一系列的网络编程组件和函数,如 Indy (Internet Direct) 库,TIdDNSResolver 等,它们可以帮助开发者处理IP与主机名的相互转换。 - Indy 是一个强大的开源网络库,包含多种协议的支持,如TCP/IP、...

    计算机软件-商业源码-实例99 获得主机名和IP地址.zip

    在本文中,我们将深入探讨这些知识点,包括网络基础、TCP/IP协议、主机名与IP地址的关系,以及如何通过编程来获取这些信息。 首先,我们要理解主机名和IP地址的基本概念。主机名是人类可读的标识符,例如...

    C#通过IP地址获取主机名称

    在DNS(Domain Name System)系统中,IP地址和主机名称可以相互转换。 在C#中,我们可以使用`System.Net.Dns`命名空间下的类和方法来实现这个功能。具体来说,`Dns`类提供了一个静态方法`GetHostEntry`,它可以接受...

Global site tag (gtag.js) - Google Analytics