写点什么

[C 语言] 支持 IPv6 的地址查询的函数 getaddrinfo()——实践类

作者:阿里云AIoT
  • 2023-03-02
    浙江
  • 本文字数:1295 字

    阅读完需:约 4 分钟

地址查询函数的功能也就是通过主机名或者域名返回详细的主机信息,其中我们最常用的功能就是通过主机名获得主机的 IP 地址等信息。接入阿里云 IoT 平台的硬件,首先要解析 IoT 的接入 endpoint,每个产品接入域名都不同。规则是:

${productKey}.iot-as-mqtt.${regionId}.aliyuncs.com
复制代码

getaddrinfo()函数

IPv6 中引入了 getaddrinfo()的新 API,它是协议无关的,既可用于 IPv4 也可用于 IPv6。getaddrinfo()函数能够处理名字到地址以及服务到端口这两种转换,返回的是一个 addrinfo 的结构(列表)指针而不是一个地址清单。

在此强烈推荐大家用 getaddrinfo()函数替代已经过时的仅支持 IPv4 的 gethostbyname()

函数原型

用主机名或服务名获取 IP 地址头文件:,

int getaddrinfo(const char *restrict host,                 const char *restrict service,                const struct addrinfo *restrict hints,                struct addrinfo **restrict result);
复制代码

参数说明:

  • host:一个主机名或者地址串(IPv4 的点分十进制串或者 IPv6 的 16 进制串)

  • service:服务名可以是十进制的端口号,也可以是已定义的服务名称,如 ftp、http 等

  • hints:可以是一个空指针,也可以是一个指向某个 addrinfo 结构体的指针,调用者在这个结构中填入关于期望返回的信息类型的暗示。举例来说:指定的服务既可支持 TCP 也可支持 UDP,所以调用者可以把 hints 结构中的 ai_socktype 成员设置成 SOCK_DGRAM 使得返回的仅仅是适用于数据报套接口的信息。

  • result:本函数通过 result 指针参数返回一个指向 addrinfo 结构体链表的指针。

返回值:

  • 若成功,返回 0;若出错,返回非 0 错误码

addrinfo 结构体:

struct addrinfo {int ai_flags;int ai_family;int ai_socktype;int ai_protocol;socklen_t ai_addrlen; //ai_addr的地址长度struct sockaddr *ai_addr;char *ai_canonname;struct addrinfo *ai_next; //指向链表的下一个结点};
复制代码

使用参考:

struct addrinfo *ai, *aip;struct addrinfo hint;struct sockaddr_in *sinp;const char *addr;int err;char buf[1024];
hint.ai_flags = AI_CANONNAME;hint.ai_family = 0;hint.ai_socktype = 0;hint.ai_protocol = 0;hint.ai_addrlen = 0;hint.ai_canonname = NULL;hint.ai_addr = NULL;hint.ai_next = NULL;
if((err = getaddrinfo("aliyun.com", NULL, &hint, &ai)) != 0) printf("ERROR: getaddrinfo error: %s\n", gai_strerror(err));
for(aip = ai; aip != NULL; aip = aip->ai_next){ print_family(aip); print_type(aip); print_protocol(aip); print_flags(aip); printf("\n"); printf("Canonical Name: %s\n", aip->ai_canonname); if(aip->ai_family == AF_INET) { sinp = (struct sockaddr_in *)aip->ai_addr; addr = inet_ntop(AF_INET, &sinp->sin_addr, buf, sizeof buf); printf("IP Address: %s ", addr); printf("Port: %d\n", ntohs(sinp->sin_port)); } printf("\n");}
复制代码


物联网平台产品介绍详情:​​https://www.aliyun.com/product/iot/iot_instc_public_cn​



阿里云物联网平台客户交流群

用户头像

阿里云AIoT

关注

物联网内容搬运者 2022-04-22 加入

还未添加个人简介

评论

发布
暂无评论
[C语言]支持IPv6的地址查询的函数getaddrinfo()——实践类_人工智能_阿里云AIoT_InfoQ写作社区