项目需要从域名解析地址,但是编译的时候提示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