2017-09-01 198 views
1

我正在阅读UNIX网络编程,并提出了一个关于练习11.4的问题,以支持gethostbyname代码IPv6。书中的答案如下:可以gethostbyname()返回一个IPv6地址吗?

#include "unp.h" 

int 
main(int argc, char **argv) 
{ 
    int     sockfd, n; 
    char    recvline[MAXLINE + 1]; 
    struct sockaddr_in servaddr; 
    struct sockaddr_in6 servaddr6; 
    struct sockaddr  *sa; 
    socklen_t   salen; 
    struct in_addr  **pptr; 
    struct hostent  *hp; 
    struct servent  *sp; 

    if (argc != 3) 
     err_quit("usage: daytimetcpcli3 <hostname> <service>"); 

    if ((hp = gethostbyname(argv[1])) == NULL) 
     err_quit("hostname error for %s: %s", argv[1], hstrerror(h_errno)); 

    if ((sp = getservbyname(argv[2], "tcp")) == NULL) 
     err_quit("getservbyname error for %s", argv[2]); 

    pptr = (struct in_addr **) hp->h_addr_list; 
    for (; *pptr != NULL; pptr++) { 
     sockfd = Socket(hp->h_addrtype, SOCK_STREAM, 0); 

     if (hp->h_addrtype == AF_INET) { 
      sa = (SA *) &servaddr; 
      salen = sizeof(servaddr); 
     } else if (hp->h_addrtype == AF_INET6) { 
      sa = (SA *) &servaddr6; 
      salen = sizeof(servaddr6); 
     } else 
      err_quit("unknown addrtype %d", hp->h_addrtype); 

     bzero(sa, salen); 
     sa->sa_family = hp->h_addrtype; 
     sock_set_port(sa, salen, sp->s_port); 
     sock_set_addr(sa, salen, *pptr); 

     printf("trying %s\n", Sock_ntop(sa, salen)); 

     if (connect(sockfd, sa, salen) == 0) 
      break;  /* success */ 
     err_ret("connect error"); 
     close(sockfd); 
    } 
    if (*pptr == NULL) 
     err_quit("unable to connect"); 

    while ((n = Read(sockfd, recvline, MAXLINE)) > 0) { 
     recvline[n] = 0; /* null terminate */ 
     Fputs(recvline, stdout); 
    } 
    exit(0); 
} 

随着对书和其他资源的信息,我发现gethostbyname不能回报的IPv6。所以我的问题是gethostbyname是否可以返回关于IPV6的信息,或者只是代码错误?

我觉得这个问题不是要取代gethostbyname,我想知道这段代码的正确性。

+0

[更换的gethostbyname IPv6地址](https://stackoverflow.com/questions/2598965/gethostbyname-replacement-for-ipv6-addresses)的可能的复制 –

+0

我的问题是,是否也'gethostbyname'在** Linux **与** Windows **中的不同,可能会有不同的表现。根据上面的代码可以返回** IPv6 **。 – handora

+0

https://stackoverflow.com/questions/504810/how-do-i-find-the-current-machines-full-hostname-in-c-hostname-and-domain-info/505546#505546和其他许多点getaddrinfo。 *耸肩* –

回答

1

gethostbyname()不再是(当前)POSIX(IEEE Std 1003.1-2008,2016版)的一部分。

It explicitly mentions

的过时h_errno外部整数,和过时gethostbyaddr()和的gethostbyname()函数被除去,与该HOST_NOT_FOUNDNO_DATANO_RECOVERY沿 ,和宏TRY_AGAIN宏。


最后POSIX版本,支持gethostbyname()是IEEE标准1003.1,2004年版,which states

struct hostent *gethostbyname(const char *name); 

[...]

的gethostbyname()函数应返回包含地址族地址的条目AF_INET名为的主机名为

它根本没有提及AF_INET6


从POSIX角度看您的问题有关

这个代码的正确性

左右。

可以回答为:

  • 是的,它使用时必须正确,依靠实现定义/专用的扩展(即用于AF_INET6支持)。
  • 没有,作为现在是正确任何更多,因为gethostbyname()已经从POSIX删除。