- 浏览: 142430 次
文章分类
最新评论
在主机名与 IP 地址的转换一节中提到的 gethostbyname 和 gethostbyaddr 函数仅仅支持 IPv4,本节将介绍一个同时支持 IPv4 和 IPv6 的 getaddrinfo 函数,它能够处理名字到地址以及服务到端口这两种转换。
其中,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 地址,那么在执行了如下的程序片段后:
res 变量将指向一个由 getaddrinfo 函数动态分配的 addrinfo 结构链表,如下图所示。
getaddrinfo 函数出错时会返回非 0 错误值,可利用 gai_strerror 函数来获取对应的描述信息。下表总结了这些错误值的名字和含义。
getaddrinfo 返回的所有存储空间都是动态分配的,这些空间可使用 freeaddrinfo 函数释放,它的 ai 参数应指向由 getaddrinfo 函数返回的第一个 addrinfo 结构,因此在调用 freeaddrinfo 函数后,就一定不能再使用这些空间中保存的数据。
和 getaddrinfo 函数相对应的是 getnameinfo 函数,它以一个套接字地址结构作为参数,返回描述其中的主机的一个字符串和描述其中的服务的另一个字符串。它也是协议无关的。
这里,sockaddr 参数指向包含待转换的协议地址结构,addrlen 是该结构的长度。host 参数和 serv 参数可分别代表用来存储返回的主机和服务字符串,它们都需要由调用者预先分配存储空间。如果不想返回主机或服务字符串,可将 hostlen 或 servlen 参数指定为 0。
flags 参数可以用于改变 getnameinfo 的操作,可指定的值及其说明如下图所示。
在此需要注意的是,当调用者知道要处理的是数据报套接字时,应设置 NI_DGRAM 标志,因为套接字地址结构中仅给出了 IP 地址和端口号,getnameinfo 无法就此确定所用的协议。
#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 无法就此确定所用的协议。
发表评论
-
Unix 域套接字与描述符的传递
2019-03-27 23:59 717在Unix 域套接字概述一节中介绍了什么是 U ... -
Unix 域套接字概述
2019-03-12 22:48 982Unix 域协议并不是一个实际的协议族,而是在 ... -
kqueue 接口
2019-03-06 00:47 699kqueue 接口是 ... -
辅助数据
2019-02-28 00:40 693辅助数据(a ... -
recv/send 和 recvmsg/sendmsg 函数
2019-01-22 00:40 1585recv 和 send ... -
inetd 守护进程介绍
2019-01-09 21:51 1061在 4.3 BSD 系统之前,很多网络服务都是 ... -
主机名与 IP 地址的转换
2018-11-14 00:20 2335在网络编程中,尽管大部分情况下操作的都是 IP ... -
SCTP 事件通知
2018-02-08 03:49 997SCTP 提供了多种可用的通知,用户可经由这些通知追踪 ... -
SCTP 套接字选项
2018-02-04 09:35 1706在获取和设置套接 ... -
SCTP 套接字编程基础函数
2018-02-04 10:08 1062SCTP 服务器可以使 ... -
SCTP 套接字编程基础概念
2018-01-18 00:10 567SCTP 套接字分为一到一套接字和一到多套接字。提供一 ... -
UDP套接字编程基础
2018-01-14 10:37 576下图显示了使用 UDP 套接字编写客户/服务器程序时的 ... -
通用套接字选项
2018-01-02 00:46 555在获取和设置套接 ... -
获取和设置套接字选项
2017-12-29 08:21 446下面几种方法可用 ... -
I/O 复用之 poll 函数
2017-12-27 00:20 429poll 函数提供的功能与 select 类似,不过在 ... -
I/O 复用之select 函数
2017-12-12 00:32 520select 函数允许进 ... -
Unix 5 种 IO 模型概述
2017-11-19 01:44 309Unix 下有 5 种可用 ... -
套接字创建、连接和关闭函数
2017-08-13 17:16 671下图是一对 TCP 客户与服务器进程之间发生的一些典型 ... -
字节转换和填充函数
2017-08-06 01:09 433网络编程中,为保证发送协议栈和接收协议栈就如 32 位 ... -
IPv4 和 IPv6 的套接字地址结构
2017-08-01 21:03 743大多数套接字函数 ...
相关推荐
// 使用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地址之间的转换是网络通信中的基础操作。易语言作为一款中国本土开发的、面向初学者的编程语言,也提供了相应的功能来实现这一转换。本篇文章将深入讲解如何...
10. **项目结构**:一个简单的IP地址与主机名转换程序可能包括一个主函数,调用`Dns.GetHostEntry`或`Dns.Resolve`方法,然后显示或存储转换结果。用户界面可能是命令行形式或者图形用户界面(GUI),如Windows ...
这段代码首先获取主机名,然后使用`getaddrinfo`函数查找与之相关的IP地址。`getaddrinfo`返回一个链表,包含了不同类型的IP地址。遍历这个链表,使用`inet_ntop`函数将二进制的IP地址转换为人类可读的形式。 需要...
`AddressList`属性是一个`IPAddress`对象数组,包含了与主机名关联的所有IP地址,包括IPv4和IPv6。 在实际应用中,我们可能只需要IPv4或IPv6地址,可以进行筛选: ```csharp IPAddress ipv4Address = null; ...
1. **DNS解析**:DNS(Domain Name System)是将主机名转换为IP地址的服务。在程序中,我们可以使用DNS查询来获取IP地址。在Python中,可以使用`socket.gethostbyname()`函数实现,如`ip_address = socket....
获取本地主机名和IP地址的MFC实现 在MFC应用程序中,获取本地主机名和IP地址是一项基本的网络编程任务。下面,我们将介绍如何使用MFC框架来实现这个功能。 首先,我们需要在StdAfx.h文件中包含afxsock.h头文件,...
3. **进行DNS解析**:对于每一行IP,使用编程语言提供的DNS库或函数(如Python的`socket.gethostbyaddr()`)进行反向解析,将IP转换为主机名。这个函数会返回一个包含主机名、域名和IP地址列表的元组,通常我们只...
在IT行业中,网络通信是不可或缺的一部分,而网络通信的基础之一就是IP地址与主机名的相互转换。本篇文章将深入探讨如何在Delphi 2009环境下编写一个小程序,实现通过IP地址获取主机名的功能。 首先,让我们了解IP...
在Windows系统中,如果你需要通过编程方式获取本机的主机名和IP地址,可以使用Winsock库中的函数。Winsock是Windows Socket接口的简称,它为应用程序提供了标准的网络通信功能。下面我们将详细讨论如何利用Winsock库...
如果需要将主机名转换为IP地址,可以使用`gethostbyname`函数。这个函数接收主机名作为参数,返回一个`hostent`结构体,其中包含了IP地址等信息。结构体中的`h_addr_list`成员包含了IP地址列表。注意,对于IPv4,...
在IT领域,网络通信是不可或缺的一部分,而主机名与IP地址之间的转换是网络通信中的基本操作。本篇文章将深入探讨如何在Unix/Linux环境下,利用C语言通过IP地址获取主机名的相关知识点。 首先,我们需要理解IP地址...
在这个主题中,“MFC获取主机名,IP地址,MAC地址”指的是如何在MFC应用中获取计算机的相关网络信息。 首先,获取主机名是通过Windows API函数`GetComputerName`来完成的。这个函数允许程序获取当前系统的计算机名...
在IT领域,获取本机主机名和IP地址是常见的网络编程任务,这涉及到操作系统与网络接口的交互。本文将详细讲解这两个概念以及如何在不同环境下实现获取。 首先,主机名是一个标识符,用于唯一地识别网络上的计算机。...
标题 "转换IP地址为主机名的控件" 描述了这样一个功能:将数字形式的IP地址转换成人类可读的主机名。在计算机网络中,IP地址是标识网络上设备的唯一数字序列,而主机名则是一种便于记忆的字符串形式。这个控件可能是...
- Delphi提供了一系列的网络编程组件和函数,如 Indy (Internet Direct) 库,TIdDNSResolver 等,它们可以帮助开发者处理IP与主机名的相互转换。 - Indy 是一个强大的开源网络库,包含多种协议的支持,如TCP/IP、...
很简单的一个例子,用delphi2010编写的,网上有的例子会出现网上的教程是Pchar(IPAddress) 这样会提示 Incompatible types: 'Char' and 'AnsiChar' 处理 解决办法1:参数格式不变,使用的时候麻烦一点。先把...
在本文中,我们将深入探讨这些知识点,包括网络基础、TCP/IP协议、主机名与IP地址的关系,以及如何通过编程来获取这些信息。 首先,我们要理解主机名和IP地址的基本概念。主机名是人类可读的标识符,例如...