getaddrinfo()返回几个相同的结果

getaddrinfo()返回几个相同的结果,第1张

概述在/ etc / hosts我有: 127.0.0.1 localhost.localdomain localhost::1 localhost.localdomain localhost 测试程序: #include <string.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#inclu 在/ etc / hosts我有:

127.0.0.1   localhost.localdomain   localhost::1     localhost.localdomain   localhost

测试程序:

#include <string.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <netdb.h>#include <netinet/in.h>const char* family_to_string(int family){    return family == AF_INET ? "AF_INET"        : family == AF_INET6 ? "AF_INET6"        : "<unkNown>";}const char* socktype_to_string(int socktype){    return socktype == SOCK_STREAM ? "SOCK_STREAM"        : socktype == SOCK_DGRAM ? "SOCK_DGRAM"        : "<unkNown>";}const char* protocol_to_string(int protocol){    return protocol == IPPROTO_TCP ? "IPPROTO_TCP"        : protocol == IPPROTO_UDP ? "IPPROTO_UDP"        : "<unkNown>";}voID print_addrinfo(struct addrinfo *ai){    int r;    char hbuf[NI_MAXHOST],sbuf[NI_MAXSERV];    r = getnameinfo(ai->ai_addr,ai->ai_addrlen,hbuf,sizeof(hbuf),sbuf,sizeof(sbuf),NI_NUMERICHOST | NI_NUMERICSERV);    if (r)    {        fputs("getnameinfo\n",stderr);        exit(EXIT_FAILURE);    }    const char *family = family_to_string(ai->ai_family);    const char *socktype = socktype_to_string(ai->ai_socktype);    const char *protocol = protocol_to_string(ai->ai_protocol);    const char *family2 = family_to_string(ai->ai_addr->sa_family);    printf("flags=%i,family=%s,socktype=%s,protocol=%s,host=%s,serv=%s\n",ai->ai_flags,family,socktype,protocol,family2,sbuf);}int main(int argc,char *argv[]){    (voID)argc;    (voID)argv;    int r;    struct addrinfo hints;    struct addrinfo *result,*ai;    memset(&hints,sizeof(struct addrinfo));    // hints.ai_family = AF_INET;    hints.ai_socktype = SOCK_STREAM;    r = getaddrinfo("localhost","8000",&hints,&result);    if (r)    {        fputs("getaddrinfo\n",stderr);        exit(EXIT_FAILURE);    }    ai = result;    while (ai)    {        print_addrinfo(ai);        ai = ai->ai_next;    }    exit(EXIT_SUCCESS);}

当我没有设置hints.ai_family时,它就像预期的那样:

$gcc -Wall -Wextra -Werror -pedantic -pedantic-errors -g -gDWarf-2 -g3 % && ./a.outflags=0,family=AF_INET6,socktype=SOCK_STREAM,protocol=IPPROTO_TCP,host=::1,serv=8000flags=0,family=AF_INET,host=127.0.0.1,serv=8000

使用hints.ai_family,它返回两个相同的addrinfo结构:

flags=0,serv=8000

你能解释一下发生了什么吗?我认为提示充当过滤器.也就是说,在这种情况下只返回一个结果.

UPD /etc/nsswitch.conf

# Begin /etc/nsswitch.confpasswd: compat mymachines systemdgroup: compat mymachines systemdshadow: compatpublickey: fileshosts: files mymachines resolve [!UNAVAIL=return] dns myhostnamenetworks: filesprotocols: filesservices: filesethers: filesrpc: filesnetgroup: files# End /etc/nsswitch.conf

在/etc/resolv.conf:

# Generated by resolvconfsearch Dlinknameserver 192.168.0.1

192.168.0.1是我的路由器.我的IP地址是192.168.0.39.

解决方法 从我所看到的:

sysdeps/posix/getaddrinfo.c:2206

intgetaddrinfo (const char *name,const char *service,const struct addrinfo *hints,struct addrinfo **pai)

sysdeps/posix/getaddrinfo.c:2304

last_i = gaih_inet (name,pservice,hints,end,&naddrs,&tmpbuf);

sysdeps/posix/getaddrinfo.c:342

static intgaih_inet (const char *name,const struct gaih_service *service,const struct addrinfo *req,struct addrinfo **pai,unsigned int *naddrs,struct scratch_buffer *tmpbuf)

sysdeps/posix/getaddrinfo.c:595

rc = __gethostbyname2_r (name,AF_INET,&th,tmpbuf->data,tmpbuf->length,&h,&h_errno);

nss/getXXbyYY_r.c:189

intINTERNAL (REENTRANT_name) (ADD_ParaMS,LOOKUP_TYPE *resbuf,char *buffer,size_t buflen,LOOKUP_TYPE **result H_ERRNO_PARM                           EXTRA_ParaMS)

nss/getXXbyYY_r.c:316

status = DL_CALL_FCT (fct.l,(ADD_VARIABLES,resbuf,buffer,buflen,&errno H_ERRNO_VAR EXTRA_VARIABLES));

nss/nss_files/files-hosts.c:385

enum nss_status_nss_files_gethostbyname2_r (const char *name,int af,struct hostent *result,int *errnop,int *herrnop)

nss/nss_files/files-hosts.c:389

return _nss_files_gethostbyname3_r (name,af,result,errnop,herrnop,NulL,NulL);

nss/nss_files/files-hosts.c:334

enum nss_status_nss_files_gethostbyname3_r (const char *name,int *herrnop,int32_t *ttlp,char **canonp)

这里我们得到第一个匹配,并且 – 如果在/etc/host.conf中打开了多个 – 其余部分:

nss/nss_files/files-hosts.c:352

while ((status = internal_getent (stream,flags))       == NSS_STATUS_SUCCESS)  {    LOOKUP_name_CASE (h_name,h_aliases)  }if (status == NSS_STATUS_SUCCESS    && _res_hconf.flags & HCONF_FLAG_MulTI)  status = gethostbyname3_multi    (stream,name,flags);

nss/nss_files/files-hosts.c:127

static enum nss_statusgethostbyname3_multi (file * stream,const char *name,int flags)

nss/nss_files/files-hosts.c:162

status = internal_getent (stream,&tmp_result_buf,tmp_buffer.data,tmp_buffer.length,flags);

nss/nss_files/files-XXX.c:178

static enum nss_statusinternal_getent (file *stream,struct STRUCTURE *result,int *errnop H_ERRNO_PROTO                 EXTRA_ARGS_DECL)

nss/nss_files/files-XXX.c:222

|| ! (parse_result = parse_line (p,data,errnop                                 EXTRA_ARGS)));

这里我们解析“:: 1 localhost.localdomain localhost”行.我们试图
运行inet_pton over :: 1.那失败了,因为af == AF_INET.然后我们
请注意:: 1是IPv6环回地址,因此我们返回IPv4环回
地址:

nss/nss_files/files-hosts.c:51

liNE_PARSER

nss/nss_files/files-hosts.c:59

if (inet_pton (af == AF_Unspec ? AF_INET : af,addr,entdata->host_addr)    > 0)  af = af == AF_Unspec ? AF_INET : af;else  {    if (...)      ...    else if (af == AF_INET             && inet_pton (AF_INET6,entdata->host_addr) > 0)      {        if (...)          ...        else if (IN6_IS_ADDR_LOOPBACK (entdata->host_addr))          {            in_addr_t localhost = htonl (INADDR_LOOPBACK);            memcpy (entdata->host_addr,&localhost,sizeof (localhost));          }

也许有人会在mailing list回复,我们会学到更多.

总结

以上是内存溢出为你收集整理的getaddrinfo()返回几个相同的结果全部内容,希望文章能够帮你解决getaddrinfo()返回几个相同的结果所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1229037.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存