百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

gethostbyname()、getaddrinfo()函数基本情况

toyiye 2024-07-02 02:57 26 浏览 0 评论

1. gethostbyname

函数:struct hostent *gethostbyname(const char *name)

头文件 #include <netdb.h>

返回hostent结构体类型指针:

struct hostent {
     char  *h_name;         /* official name of host */
     char **h_aliases;         /* alias list */
     int    h_addrtype;       /* host address type */
     int    h_length;         /* length of address */
     char **h_addr_list;        /* list of addresses */
 }

这个函数的局限是只能返回IPv4地址,并且不允许调用者指定所需地址类型的任何信息,返回的结构只包含了用于存储 IPv4 地址的空间。POSIX规范预警可能会在将来某个版本中撤销gethostbyname函数。

从POSIX规范中撤销该函数意在声明新的程序不该在使用它,鼓励在新的程序中改用getaddrinfo函数。

函数原型:

int gethostbyname_r(const char *name,
                    struct hostent *ret, 
                    char *buf, 
                    size_t buflen,
                    struct hostent **result,
                    int *h_errnop);

gethostbyname_r()函数是gethostbyname()函数的可重入版本,两个函数的功能是一样的。

2. gethostbyname2

函数:struct hostent *gethostbyname2(const char *name, int af);

它的工作原理类似于gethostbyname(),但是允许指定地址必须属于的地址族,当af参数为AF_INET时,gethostbyname2和gethostbyname一样,即查找并返回IPv4地址。当af参数为AF_INET6时,gethostbyname2只查找AAAA记录并且返回IPv6地址。

头文件:同上。

返回hostent结构体类型指针:同上。

函数原型:

int gethostbyname2_r(const char *name, 
                     int af,
                     struct hostent *ret, 
                     char *buf, 
                     size_t buflen,
                     struct hostent **result, 
                     int *h_errnop);

gethostbyname2_r()函数是gethostbyname2()函数的可重入版本,两个函数的功能是一样的。

3. getaddrinfo

函数将主机名、主机地址、服务名和端口的字符串表示转换成套接字地址结构体。它是已弃用的getgostbyname和getservbyname函数的新的替代品。和以前的那些函数不同,这个函数是可以重入的,适合于任何协议,函数把协议相关性完全隐藏在这个库函数内部。应用程序只要处理由getaddrinfo函数填写的套接口地址结构。

函数原型:

int getaddrinfo( const char *node, 
                 const char *service,
                 const struct addrinfo *hints,
                 struct addrinfo **res);

1)nodename:节点名可以是主机名,也可以是数字地址。(IPV4的10进点分,或是IPV6的16进制);

2)servname:包含十进制数的端口号或服务名如(ftp,http);

3)hints:是一个空指针或指向一个addrinfo结构的指针,由调用者填写关于它所想返回的信息类型的线索;

4)res:存放返回addrinfo结构链表的指针;

头文件:

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
 
void freeaddrinfo(struct addrinfo *res);
const char *gai_strerror(int errcode);
 
 struct addrinfo {
          int              ai_flags;
          int              ai_family;
          int              ai_socktype;
          int              ai_protocol;
          socklen_t        ai_addrlen;
          struct sockaddr  *ai_addr;
          char            *ai_canonname;
          struct addrinfo   *ai_next;
 }

参数说明:

在getaddrinfo函数之前通常需要对以下6个参数进行以下设置:nodename、servname、hints的ai_flags、ai_family、ai_socktype、ai_protocol。在6项参数中,对函数影响最大的是nodename,sername和hints.ai_flag。而ai_family只是有地址为v4地址或v6地址的区别。而ai_protocol一般是为0不作改动。

其中ai_flags、ai_family、ai_socktype说明如下:

参数

取值

说明

ai_family

AF_INET

2

IPv4


AF_INET6

23

IPV6


AF_UNSPEC

0

协议无关

—-

—-

—-

ai_protocol

IPPROTO_IP

0

IP协议


IPPROTO_IPv4

4

IPv4


IPPROTO_IPv6

41

IPv6


IPPROTO_UDP

17

UDP


IPPROTO_TCP

6

TCP

—-

—-

ai_socktype

SOCK_STREAM

1


SOCK_DGRAM

2

数据报

—-

—-

ai_flags

AI_PASSIVE

1

被动的,用于bind,
通常用于 server socket


AI_CANONNAME

2



AI_NUMERICHOST

4

地址为数字串

对于ai_flags值的说明:

AI_PASSIVE

AI_CANONNAME

AI_NUMERICHOST

0/1

0/1

0/1

如上表所示,ai_flagsde值范围为0~7,取决于程序如何设置3个标志位,比如设置ai_flags为 “AI_PASSIVE|AI_CANONNAME”,ai_flags值就为3。

三个参数的含义分别为:

(1)AI_PASSIVE 当此标志置位时,表示调用者将在bind()函数调用中使用返回的地址结构。当此标志不置位时,表示将在connect()函数调用中使用。当节点名为NULL,且此标志置位,则返回的地址将是通配地址。如果节点名为NULL,且此标志不置位,则返回的地址将是回环地址。

(2)AI_CANNONAME当此标志置位时,在函数所返回的第一个addrinfo结构中的ai_cannoname成员中,应该包含一个以空字符结尾的字符串,字符串的内容是节点名的正规名。

(3)AI_NUMERICHOST当此标志置位时,此标志表示调用中的节点名必须是一个数字地址字符串。

给定host和service(套接字地址的两个组成部分),getaddrinfo返回result, result是一个指向addrinfo结构的链表,其中每个结构体指向一个对应于host和service的套接字地址结构。

在客户端调用了getaddrinfo之后,会遍历这个列表,一次尝试每一个套接字地址,直到调用socket和connect成功,建立起连接。类似地,服务器会尝试遍历列表中的每一个套接字的地址,直到调用socket和bind成功,描述符会被绑定到一个合法的套接字地址。为了避免内存泄漏,应用程序必须调用freeaddrinfo,释放该链表。如果getaddrinfo返回非零的错误代码,应用程序可以调用gai_streeror,将代码转成消息串。

getaddrinfo的host参数可以是域名,也可以是数字地址(如点分十进制IP地址)。service参数可以是服务名(如http),也可以是十进制端口号。如果不想把主机名转换成地址,可以把host设置为NULL。对service来说也是一样。但是必须指定两者中至少一个。

getaddrinfo一个很好的方面是addrinfo结构中的字段是不透明的,即它们可以直接传递给套接字接口中的函数,应程序代码无需再做任何处理。例如,ai_family、ai_socktype和ai_protocol可以直接传递给socket。类似的,ai_addr和ai_addrlen可以直接传递给connect和bind。这个强大的属性使得我们编写客户端和服务器能够独立于某一个特殊版本的IP协议。

4.关于上面几个函数线程安全如下表所示:

gethostbyname处理数据时返回的结果是存储在一个静态结构体变量中的,作为本地的一个全局变量,只初始化一次,也就是说,下次对这个变量进行操作时,是基于这次的结果来操作的。

下面小例子说明这个问题:

ht1 = gethostbyname(“www.sohu.com”);
ht2 = gethostbyname(“www.baidu.com”);
 
printf("ip:%s\n",inet_ntop(ht1->h_addrtype,ht1->h_addr_list[i],str,30));
printf(":%s\n",ht1->h_aliases[i]);
 
printf("IP:%s\n",inet_ntop(ht2->h_addrtype,ht2->h_addr_list[i],str,30));
printf("alias:%s\n",ht2->h_aliases[i]);

ht1和ht2这个结构体指针在运行gethostbyname这个函数后指向的是同一个地址(即上面gethostbyname存储返回结果的变量地址)(大家可以在编译器里分部执行查看变量值的变化)

5.小结

应用程序用来把主机名转换成IP地址,gethostbyname是曾经常用的入口。随着向IPv6和线程化编程模型的转移,getaddrinfo显得更有用,因为它既解析IPv6地址,又符合线程安全。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码