socket方式
- Sockect方式可以通过getaddrinfo(支持IPV4/IPV6),进行域名解析
- 注意:getaddrinfo无法解决主机名localhost,获取IP地址的情况
- getaddrinfo函数原型
int getaddrinfo( const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result );
- hostname 主机名或地址串
- service 服务名
- hints 可以是空指针,也可以是addrinfo结构体的指针。
- result,返回一个指向addrinfo结构体链表的指针
- 函数返回值:0成功,非0失败。
struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
char *ai_canonname;
struct sockaddr *ai_addr;
struct addrinfo *ai_next;
};
- getaddrinfo,支持IPV4,IPV6。gethostbyname函数不支持IPV6。另外这两个函数都是阻塞方式的。
- 代码
#include<netdb.h>
bool dnsLookup(std::string &server, std::string& serverIP)
{
bool ret = false;
serverIP = "";
char ipStr[17];
bzero(ipStr, 17);
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
hints.ai_protocol = NCCLOUD_IP_V4;
struct addrinfo* result = NULL;
INT isSuccess = getaddrinfo(server.getString(), NULL, &hints, &result);
if (isSuccess != 0) {
}
else {
for (struct addrinfo *ptr = result; ptr != NULL; ptr = ptr->ai_next) {
struct sockaddr_in* sa = (struct sockaddr_in*) ptr->ai_addr;
if (NULL != sa) {
inet_ntop(AF_INET, &sa->sin_addr.s_addr, ipStr, sizeof(ipStr));
serverIP = ipStr;
ret = true;
}
break;
}
}
freeaddrinfo(result);
return ret;
}
libcurl方式
#include <curl/curl.h>
void dnsLookup()
{
CURL *curl;
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
CURLcode res;
res = curl_easy_perform(curl);
char *ip = NULL;
if((res == CURLE_OK) &&
!curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP, &ip) && ip) {
printf("IP: %s\n", ip);
}
curl_easy_cleanup(curl);
curl_global_cleanup();
}