IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    gethostbyname替代getaddrinfo

    admin发表于 2015-05-19 06:38:28
    love 0

    项目需要从域名解析地址,但是编译的时候提示gethostbyname error,百度了一下,这才发现,原来用了N年的gethostbyname 已经是obsolete 的函数了,都标记成DEPRECATED 了,无论是windows 下还是linux 下都建议使用getaddrinfo 来替代它。很好的总结经验:

    gethostbyname函数的原型如下:

    struct hostent* FAR gethostbyname(
      _In_  const char *name
    );

    之前使用gethostbyname 很简单,类似这样:

    struct hostent *remoteHost;
    struct in_addr addr;
    
    if ( ( remoteHost = gethostbyname( hostname ) ) == NULL ){
        xxxx;
    }
    else{
        if (remoteHost->h_addrtype == AF_INET)
        {
            while (remoteHost->h_addr_list[i] != 0) {
                addr.s_addr = *(u_long *) remoteHost->h_addr_list[i++];
                printf("\tIP Address #%d: %s\n", i, inet_ntoa(addr));
            }
        }
    }

    现在得用getaddrinfo,其原型如下:

    int WSAAPI getaddrinfo(
      _In_opt_  PCSTR pNodeName,
      _In_opt_  PCSTR pServiceName,
      _In_opt_  const ADDRINFOA *pHints,
      _Out_     PADDRINFOA *ppResult
    );

    得这么用:

    struct addrinfo *result = NULL;
    struct addrinfo *ptr = NULL;
    struct addrinfo hints;
    
    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    
    dwRetval = getaddrinfo(hostname, 0, &hints, &result);
    if ( dwRetval != 0 ) {
        xxxx;
    }
    else{
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
    
        printf("getaddrinfo response %d\n", i++);
        printf("\tFlags: 0x%x\n", ptr->ai_flags);
        printf("\tFamily: ");
        switch (ptr->ai_family) {
            case AF_UNSPEC:
                printf("Unspecified\n");
                break;
            case AF_INET:
                printf("AF_INET (IPv4)\n");
                sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
                printf("\tIPv4 address %s\n",
                    inet_ntoa(sockaddr_ipv4->sin_addr) );
                break;
            case AF_INET6:
                printf("AF_INET6 (IPv6)\n");
                // the InetNtop function is available on Windows Vista and later
                // sockaddr_ipv6 = (struct sockaddr_in6 *) ptr->ai_addr;
                // printf("\tIPv6 address %s\n",
                //    InetNtop(AF_INET6, &sockaddr_ipv6->sin6_addr, ipstringbuffer, 46) );
    
                // We use WSAAddressToString since it is supported on Windows XP and later
                sockaddr_ip = (LPSOCKADDR) ptr->ai_addr;
                // The buffer length is changed by each call to WSAAddresstoString
                // So we need to set it for each iteration through the loop for safety
                ipbufferlength = 46;
                iRetval = WSAAddressToString(sockaddr_ip, (DWORD) ptr->ai_addrlen, NULL, 
                    ipstringbuffer, &ipbufferlength );
                if (iRetval)
                    printf("WSAAddressToString failed with %u\n", WSAGetLastError() );
                else    
                    printf("\tIPv6 address %s\n", ipstringbuffer);
                break;
            case AF_NETBIOS:
                printf("AF_NETBIOS (NetBIOS)\n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_family);
                break;
        }
    }

    转载自:mosir.org

    原创文章,转载请注明: 转载自C/C++程序员之家

    本文链接地址: gethostbyname替代getaddrinfo



沪ICP备19023445号-2号
友情链接