打印

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

[复制链接]
358|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
IoT8888|  楼主 | 2019-11-7 16:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 IoT8888 于 2019-11-7 16:45 编辑
简介: C语言硬件开发中,使用支持IPv6地址查询的函数getaddrinfo()替代gethostbyname()

地址查询函数的功能也就是通过主机名或者域名返回详细的主机信息,其中我们最常用的功能就是通过主机名获得主机的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结构体:

<pre data-spm-anchor-id="a2c6h.12873639.0.i8.3554569dKMvJvz" style="box-sizing: border-box; overflow: auto; font-family: SFMono-Regular, Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; font-size: 13.6px; margin-bottom: 16px; padding: 16px; overflow-wrap: normal; background-color: rgb(246, 248, 250); border-radius: 3px; line-height: 1.45; color: rgb(36, 41, 46);"><code class="hljs cpp" style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; display: inline; overflow: visible; color: rgb(56, 58, 66); background: transparent; border-radius: 3px; border: 0px; word-break: normal; line-height: inherit; overflow-wrap: normal;"><span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">struct</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(193, 132, 1);">addrinfo</span> {</span>
<span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">int</span> ai_flags;
<span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">int</span> ai_family;
<span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">int</span> ai_socktype;
<span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">int</span> ai_protocol;
<span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">socklen_t</span> ai_addrlen; <span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">//ai_addr的地址长度</span>
<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">struct</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(193, 132, 1);">sockaddr</span> *<span class="hljs-title" style="box-sizing: border-box; color: rgb(193, 132, 1);">ai_addr</span>;</span>
<span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">char</span> *ai_canonname;
<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">struct</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(193, 132, 1);">addrinfo</span> *<span class="hljs-title" style="box-sizing: border-box; color: rgb(193, 132, 1);">ai_next</span>;</span> <span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">//指向链表的下一个结点</span>
};</code></pre>

使用参考:

<pre data-spm-anchor-id="a2c6h.12873639.0.i10.3554569dKMvJvz" style="box-sizing: border-box; overflow: auto; font-family: SFMono-Regular, Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; font-size: 13.6px; padding: 16px; overflow-wrap: normal; background-color: rgb(246, 248, 250); border-radius: 3px; line-height: 1.45; color: rgb(36, 41, 46);"><code class="hljs mipsasm" data-spm-anchor-id="a2c6h.12873639.0.i15.3554569dKMvJvz" style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; display: inline; overflow: visible; color: rgb(56, 58, 66); background: transparent; border-radius: 3px; border: 0px; word-break: normal; line-height: inherit; overflow-wrap: normal;">struct <span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">addrinfo </span>*ai, *aip<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
struct <span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">addrinfo </span>hint<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
struct sockaddr_in *sinp<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
const char *<span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">addr;
</span>int err<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
char <span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">buf[1024];
</span>
hint.ai_flags = AI_CANONNAME<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
hint.ai_family = <span class="hljs-number" style="box-sizing: border-box; color: rgb(152, 104, 1);">0</span><span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
hint.ai_socktype = <span class="hljs-number" style="box-sizing: border-box; color: rgb(152, 104, 1);">0</span><span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
hint.ai_protocol = <span class="hljs-number" style="box-sizing: border-box; color: rgb(152, 104, 1);">0</span><span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
hint.ai_addrlen = <span class="hljs-number" style="box-sizing: border-box; color: rgb(152, 104, 1);">0</span><span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
hint.ai_canonname = NULL<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
hint.ai_addr = NULL<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
hint.ai_next = NULL<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>

if((err = getaddrinfo(<span class="hljs-string" style="box-sizing: border-box; color: rgb(80, 161, 79);">"aliyun.com"</span>, NULL, &hint, &ai)) != <span class="hljs-number" style="box-sizing: border-box; color: rgb(152, 104, 1);">0</span>)
    printf(<span class="hljs-string" style="box-sizing: border-box; color: rgb(80, 161, 79);">"ERROR: getaddrinfo error: %s\n"</span>, gai_strerror(err))<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>

for(aip = ai<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">; aip != NULL; aip = aip->ai_next)</span>
{
    print_family(aip)<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
    print_type(aip)<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
    print_protocol(aip)<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
    print_flags(aip)<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
    printf(<span class="hljs-string" style="box-sizing: border-box; color: rgb(80, 161, 79);">"\n"</span>)<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
    printf(<span class="hljs-string" style="box-sizing: border-box; color: rgb(80, 161, 79);">"Canonical Name: %s\n"</span>, aip->ai_canonname)<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
    if(aip->ai_family == AF_INET)
    {
        sinp = (struct sockaddr_in *)aip->ai_addr<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
        <span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">addr </span>= inet_ntop(AF_INET, &sinp->sin_addr, <span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">buf, </span>sizeof <span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">buf);
</span>        printf(<span class="hljs-string" style="box-sizing: border-box; color: rgb(80, 161, 79);">"IP Address: %s "</span>, <span class="hljs-keyword" style="box-sizing: border-box; color: rgb(166, 38, 164);">addr);
</span>        printf(<span class="hljs-string" style="box-sizing: border-box; color: rgb(80, 161, 79);">"Port: %d\n"</span>, ntohs(sinp->sin_port))<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
    }
    printf(<span class="hljs-string" style="box-sizing: border-box; color: rgb(80, 161, 79);">"\n"</span>)<span class="hljs-comment" style="box-sizing: border-box; color: rgb(160, 161, 167); font-style: italic;">;</span>
}</code></pre>

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

14

帖子

0

粉丝