Misformatted domain name 之解决方案

【背景】
项目中用到c-ares 64位,是Windows + 2010组合,编译比较简单,直接有工程,简单修改相关配置,就编译成功了。但是写demo测试时,碰到"Misformatted domain name"错误。于是简单排查了一下,过程记录一下,以备不时查询。

【过程】

来自网上的代码片:
#include "test_cares.h"

#include "ares.h"

#include <time.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

#if defined (WIN32) || defined (WIN64)
#	pragma comment(lib, "ws2_32.lib")
#else
#	include <netdb.h>
#	include <arpa/inet.h>
#endif

void dns_callback (void* arg, int status, int timeouts, struct hostent* host)
{
    if(status == ARES_SUCCESS)
    {
        std::cout <<"ip : "<<"8.8.8.8"<<std::endl<<"host name : "<< host->h_name << "\n";
    }
    else
    {
        std::cout << "lookup failed: " << status << '\n';
    }
}

void main_loop(ares_channel &channel)
{
    int nfds, count;
    fd_set readers, writers;
    timeval tv, *tvp;

    while (1) 
	{
        FD_ZERO(&readers);
        FD_ZERO(&writers);
    
		nfds = ares_fds(channel, &readers, &writers);
        
		if (nfds == 0)
          break;
        
		tvp = ares_timeout(channel, NULL, &tv);
        count = select(nfds, &readers, &writers, NULL, tvp);
        ares_process(channel, &readers, &writers);
     }
}

int DEMO::get_url_by_ip(char* in_ip/* = "8.8.8.8"*/)
{
	// 注释0
#if 0
	int version;
	const char* pversion = ares_version(&version);
	std::cout<<"version : "<<pversion<<std::endl;

	struct in_addr ip_test;
	ares_inet_pton(AF_INET, in_ip, &ip_test);

	char szIP[1024];
	ares_inet_ntop(AF_INET, &ip_test, szIP, 1024);
#endif

	// 注释1
	WSADATA wsData;  
	::WSAStartup(MAKEWORD(2,2), &wsData); 

	// 注释2
	int rc1 = ares_library_init(ARES_LIB_INIT_ALL);

	ares_channel channel;
	int rc2 = ares_init(&channel);

	if(rc2 != ARES_SUCCESS) 
	{
		const char* err = ares_strerror(rc2);
		std::cout << "ares_init fail : code=" << rc2 <<", err="<<err<< std::endl;
		return -1;
	}

    struct in_addr ip;
	ares_inet_pton(AF_INET, in_ip, &ip);

    ares_gethostbyaddr(channel, &ip, sizeof ip, AF_INET, dns_callback, NULL);
    main_loop(channel);
    std::cout<<"ares test finish"<<std::endl;

    return 0;
  }


google来的代码片没有【注释0】,【注释1】,【注释2】 三个部分。


调试,第一次报错信息为:"c-ares library initialization not yet performed"

这个简单,一看文档就发现【注释2】部分,加个初始化函数就行,当然实际使用要注意调用相应的清理函数。


继续调试,第二次报错信息为:"Misformatted domain name"

这个错误查不到什么有用的资料,那就做个简单测试。

先来看看c-ares的基本函数能不能用。于是加入【注释0】部分代码,发现工作全部正常。

ok,那么库应该没问题了,可以从使用的角度切入。


那就调试进源码看看,发现报错位置在init_by_defaults里调用gethostname时返回失败。

顺手查一下gethostname的失败原因,baidu到的简单粗暴:

调用gethostname之前, 要先调用WSAStartup才可以, 否则gethostname会失败!


于是加上【注释1】的代码进行初始化,继续调试,成功。

猜你喜欢

转载自blog.csdn.net/sepnineth/article/details/78788328