LWIP应用开发|DNS域名解析

DNS域名解析

1. 域名解析过程

从用户输入一个网址到网页最终展现到用户面前,中间究竟发生了什么?下面两张图展示了其大致的流程:
在这里插入图片描述
在这里插入图片描述
域名的分层结构如下图所示,想要使用DNS域名解析功能,必须要知道域名服务器地址(一般配置为路由器地址)

在这里插入图片描述

2. DNS应用实例

以下实例完成的功能为:利用 gethostbyname() 函数,通过网址(www.baidu.com)找到相对应的IP地址

//netdb.h
/** @ingroup netdbapi */
#define gethostbyname(name) lwip_gethostbyname(name)
struct hostent *lwip_gethostbyname(const char *name);
struct hostent {
    
    
    char  *h_name;      /* 正式主机名 */
    char **h_aliases;   /* 主机别名*/
    int    h_addrtype;  /* 主机IP地址类型 */
    int    h_length;    /* 主机IP地址字节长度*/
    char **h_addr_list; /* 主机的IP地址列表*/
};
  • 参考Socket API编程优化一文,在该文的工程源码基础上进行修改
  • DNS宏开关:将opt.h文件中的LWIP_DNS宏定义开启
//opt.h文件中
/**
 * LWIP_DNS==1: Turn on DNS module.
 */
#if !defined LWIP_DNS || defined __DOXYGEN__
#define LWIP_DNS         		1
#endif
  • 配置DNS服务器:在dns.c文件中手动添加DNS服务器地址
//dns.c文件中手动添加DNS服务器地址
/** DNS server IP address */
#ifndef DNS_SERVER_ADDRESS
extern ip4_addr_t gw;   //网关地址
#define DNS_SERVER_ADDRESS(ipaddr)	(memcpy(ipaddr, &gw, sizeof(ip4_addr_t)))
#endif
  • 文件lwip.c修改代码:STM32CubeMX生成的MX_LWIP_init()函数中tcpip_init()的初始化在ip地址初始化之前,这里应该调整到IP地址初始化之后

注意:以下网关地址要填充到DNS_SERVER_ADDRESS地址中,注意要与所连路由器的网关地址一致

 /* IP addresses initialization */
  IP_ADDRESS[0] = 192;
  IP_ADDRESS[1] = 168;
  IP_ADDRESS[2] = 1;
  IP_ADDRESS[3] = 10;
  NETMASK_ADDRESS[0] = 255;
  NETMASK_ADDRESS[1] = 255;
  NETMASK_ADDRESS[2] = 255;
  NETMASK_ADDRESS[3] = 0;
  GATEWAY_ADDRESS[0] = 192;		
  GATEWAY_ADDRESS[1] = 168;
  GATEWAY_ADDRESS[2] = 1;
  GATEWAY_ADDRESS[3] = 1;  
 /* IP addresses initialization without DHCP (IPv4) */
  IP4_ADDR(&ipaddr, IP_ADDRESS[0], IP_ADDRESS[1], IP_ADDRESS[2], IP_ADDRESS[3]);
  IP4_ADDR(&netmask, NETMASK_ADDRESS[0], NETMASK_ADDRESS[1] , NETMASK_ADDRESS[2], NETMASK_ADDRESS[3]);
  IP4_ADDR(&gw, GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], GATEWAY_ADDRESS[3]);	
  /* Initilialize the LwIP stack with RTOS */
  tcpip_init( NULL, NULL );	//调整到IP地址初始化之后
  • 在工程中创建dns_client.c和对应的头文件
#include "dns_client.h"
#include "ctype.h"
#include "FreeRTOS.h"
#include "task.h"
#include "netdb.h"

void vDnsClientTask(void){
    
    
  int i;
  struct sockaddr_in server_addr;
  //dns 域名解析功能
  struct hostent *p_hostent = NULL;	
  p_hostent = gethostbyname("www.makeru.com.cn");
  if(p_hostent){
    
    
	for(i = 0; p_hostent->h_addr_list[i]; i++){
    
    	
	  printf("host ip:%s\r\n", inet_ntoa(*p_hostent->h_addr_list[i]));	
	}
  }else{
    
    	
	printf("get host ip fail!\r\n");
  }	
}
  • 在freertos.c文件中的默认任务里面添加代码
void StartDefaultTask(void const * argument){
    
    
  /* init code for LWIP */
  MX_LWIP_Init();
  /* USER CODE BEGIN StartDefaultTask */
  printf("DNS client test!\r\n");
  /* Infinite loop */
  for(;;){
    
    
    vDnsClientTask();
	osDelay(100);
  }
  /* USER CODE END StartDefaultTask */
}
  • 编译无误下载到开发板,用网线将开发板与路由器相连。打开串口助手可以看到串口返回得到的IP地址;使用ping命令可以ping通该地址;将该IP地址输入到浏览器中可以访问百度网站

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Chuangke_Andy/article/details/114063706