Chame gethostbyname para implementar a resolução de nomes de domínio (código-fonte anexado)

Resumo do desenvolvimento de funções comuns do VC++ (lista de artigos de coluna, bem-vindo à assinatura, atualizações contínuas...) icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585 série de tutoriais sobre solução de anomalias de software C++ de entrada para proficiência (lista de artigos da coluna), bem-vindo para se inscrever e continuar atualizando...) icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931 Ferramentas de análise de software C++ desde a entrada até a coleção de casos de domínio (coluna artigo está sendo atualizado...) icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795 Noções básicas e avançadas de C/C++ (artigo da coluna, atualizado continuamente...) icon-default.png?t=N7T8https://blog.csdn.net /chenlycly/category_11931267.html        Usando soquete Ao usar um soquete para se conectar a um servidor remoto, você precisa usar IP para estabelecer um link com o servidor remoto. Você não pode usar o nome de domínio diretamente. No entanto, quando configuramos o endereço do servidor, às vezes precisamos definir o nome de domínio. Isso exige que adicionemos um módulo de resolução de nome de domínio ao código. Resolva o nome de domínio em um endereço IP antes de conectar-se ao servidor.

1. Conclua o processo de resolução de nomes de domínio

       Amigos costumam perguntar sobre o processo completo de utilização do sistema DNS para consulta de IP, aqui vamos popularizar esse processo. Os servidores DNS são divididos em três tipos: servidores DNS raiz, servidores DNS de domínio de nível superior e servidores DNS autoritativos. Os servidores DNS de domínio de nível superior são principalmente responsáveis ​​por nomes de domínio de nível superior, como com, org, net, edu, governo, etc.

       O servidor DNS raiz armazena os endereços IP de todos os servidores DNS de domínio de nível superior. O servidor de domínio de nível superior pode ser encontrado por meio do servidor raiz. Por exemplo, o nome de domínio do Baidu www.baidu.com, o servidor raiz retornará o IP endereços de todos os servidores que mantêm o domínio de nível superior com. Em seguida, você escolhe um dos servidores de domínio de nível superior para enviar uma solicitação. Depois de obter o nome de domínio, o servidor de domínio de nível superior pode fornecer o endereço do servidor autoritativo responsável pelo domínio atual. Tomando o nome de domínio do Baidu como exemplo, o servidor de domínio de nível superior retornará todos os endereços de servidor autorizados responsáveis ​​pelo domínio do Baidu. Em seguida, selecione um dos endereços do servidor autoritativo para consultar o endereço IP específico de "www.baidu.com".Finalmente, o servidor autoritativo retornará o endereço IP específico. Além disso, o servidor DNS local tem uma função de cache e os registros dentro de dois dias geralmente são armazenados em cache.

       Portanto, as etapas específicas para consultar o IP correspondente a um nome de domínio através do sistema DNS podem ser resumidas como:

  • ① O sistema operacional primeiro verifica se há um registro no arquivo de hosts locais e, em caso afirmativo, retorna diretamente o endereço IP mapeado correspondente.
  • ② Se não houver configuração no arquivo de hosts locais, o host enviará uma mensagem de consulta ao seu servidor DNS local. Se houver uma no cache do servidor DNS local, o resultado será retornado diretamente.
  • ③ Se não for encontrado no cache do servidor local, selecione um na lista de servidores DNS raiz integrados (13 no mundo, endereço IP fixo) para enviar a mensagem de consulta.
  • ④ O servidor raiz resolve o nome do sufixo no nome de domínio e informa ao servidor local uma lista de todos os servidores de nível superior responsáveis ​​pelo nome do sufixo.
  • ⑤ O servidor local seleciona um dos servidores de domínio de nível superior para enviar uma solicitação de consulta. Depois de obter o nome de domínio, o servidor de domínio de nível superior continua a analisar e retorna uma lista de todos os servidores autorizados no domínio correspondente.
  • ⑥ O servidor local então envia uma mensagem de consulta ao servidor autoritativo retornado e, finalmente, obtém um endereço IP específico de um servidor autoritativo.
  • ⑦ O host retorna o IP do resultado.

2. Chame gethostbyname para iniciar a resolução do nome de domínio       

       Então, como resolver nomes de domínio em endereços IP? Na verdade, é muito simples: basta chamar a função da API do sistema gethostbyname para alcançá-lo. Observe que a função gethostbyname pode causar congestionamento de curto prazo. A função irá primeiro para o servidor DNS configurado na placa de rede para consultar o endereço IP correspondente ao nome de domínio. Se o DNS local não puder ser consultado, ele irá para o servidor DNS remoto para consultar, por isso pode ser mais demorado.

       Portanto, precisamos colocar o código que chama a função gethostbyname em um novo thread e, em seguida, entregar as informações de IP ao thread principal após serem analisadas. O código relevante é o seguinte:

// 域名解析线程函数
UINT __stdcall QueryDomainThread( LPVOID pParam )
{
	char* lpszDomainName = (char*)pParam; 

	struct hostent *pHost = gethostbyname( lpszDomainName ); 
	if( NULL == pHost )  
	{   
		// ::PostMessage // 通知主线程域名解析失败
		return 0;   
	}

	if ( pHost->h_addr_list[0] != NULL ) 
	{ 
		u32 dwIP = (*(in_addr*)pHost->h_addr_list[0]).S_un.S_addr; 
		// ::PostMessage // 通知主线程域名解析成功,将解析出来的IP投递过去
	}  

	return 0; 
}

// 发起域名解析,创建新的线程去解析
LRESULT StartQueryDomain( char* lpszDomainName )
{
	// 此处不能直接将局部变量lpszDomainName传到线程函数中,因为启动线程的_beginthreadex返回时,线程函数不一定跑起来了
	// 所以最好搞一个成员变量或者全局变量,将lpszDomainName中的字符串拷贝下来,然后给_beginthreadex传递这个声明周期
	// 更长的变量
	strcpy( g_szMDomainName, lpszDomainName );

    // 线程函数QueryDomainThread的实现,上面已经给出
	HANDLE hThread= (HANDLE)_beginthreadex( NULL, 0, QueryDomainThread, (void*)g_szMDomainName, 0, NULL );
	if( hThread != NULL )
	{
		CloseHandle( hThread );
		return S_OK;
	}

	return S_FALSE;
}

Acho que você gosta

Origin blog.csdn.net/chenlycly/article/details/133493511
Recomendado
Clasificación