W6100-EVB-PICO做DNS Client进行域名解析(四)

前言

在上一章节中我们用W6100-EVB-PICO通过dhcp获取ip地址(网关,子网掩码,dns服务器)等信息,给我们的开发板配置网络信息,成功的接入网络中,那么本章将教大家如何让我们的开发板进行DNS域名解析,通过请求DNS服务器可以对一网络域名进行解析后获得其ip地址。

什么是DNS,有何用途?

        DNS: 连接域名与IP地址的桥梁
        在互联网的浩瀚海洋中,我们每天都在使用各种域名来访问不同的网站。例如,当我们想要观看某个视频网站时,我们只需要在浏览器中输入该网站的域名,就可以轻松地访问到该网站。那么,我们是如何通过域名来找到网站的呢?这就离不开DNS的作用
        DNS,全称Domain Name System,中文名为域名系统。它是互联网的一项重要服务,主要负责将人们所款悉的域名转换为电脑可以理解的IP地址。在互联网中,所有的信息都需要通过IP地址来进行识别和访问,而DNS就是连接域名和IP地址之间的桥梁
当我们输入一个域名时,DNS会根据这个域名返回相应的IP地址,然后我们的电脑就可以通过这个IP地址来访问对应的网站。这个过程在无形中进行,我们只需要在浏览器中输入域名即可。
DNS不仅仅是将域名转换为IP地址这么简单,它还承担着其他重要的责任。例如,当一个网站的域名被恶意攻击时,DNS可以提供一定的防护作用。另外,DNS还可以帮助我们加速网页的加载速度,提高互联网的访问效率
        总之,DNS是互联网的重要组成部分,它为我们提供了更方便、更快捷的访问方式。正是因为有了DNS,我们才能够轻松地通过域名来访问网站,了解世界各地的信息。在未来,随着互联网的发展,DNS的作用将更加重要,它将为人们提供更加优质、更加便捷的互联网服务

软硬件准备:

软件:VS code(须具有相应开发环境,具体参考第一章)

硬件;W6100-EVB-PICO开发板,网线,micro USB 数据线,路由器(可上网)

通过使用DNS协议解析百度域名

1.相关代码:

我们先找到dns.h头文件下面看下,可以看到几个函数声明,我们需要用到如下所示几个函数:

DNS_init,要我们传入dns信息的接收缓存buff地址;DNS_run根据这个函数描述,需要我们传入一个socket端口号,dns服务器ip,请求解析的域名,解析后ip存放的地址,以及模式(IPv4或IPv6);DNS_time_handler是1s定时器的处理程序,我们要把它放在一个定时器里,每到1秒调用1次,做dns解析时的计时操作,以判断是否超时,并做相应处理。

/*
 * @brief DNS process initialize
 * @param s   : Socket number for DNS
 * @param buf : Buffer for DNS message
 */
void DNS_init(uint8_t * buf);

/*
 * @brief DNS process
 * @details Send DNS query and receive DNS response
 * @param dns_ip        : DNS server ip
 * @param name          : Domain name to be queryed
 * @param ip_from_dns   : IP address from DNS server
 * @return  -1 : failed. @ref MAX_DOMIN_NAME is too small \n
 *           0 : failed  (Timeout or Parse error)\n
 *           1 : success
 * @note This funtion blocks until success or fail. max time = @ref MAX_DNS_RETRY * @ref DNS_WAIT_TIME
 */
int8_t DNS_run(uint8_t s,uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns,uint8_t mode);

/*
 * @brief DNS 1s Tick Timer handler
 * @note SHOULD BE register to your system 1s Tick timer handler
 */
void DNS_time_handler(void);

然后我们打开dns_client.c,可以看到先初始化网络信息和所需要的解析域名,这里以百度(www.baidu.com)为例,然后与上一章的dhcp类似,都是将函数封装好,然后声明后直接在主程序里调用。如下所示。

#define ETHERNET_BUF_MAX_SIZE (1024 * 2)

void network_init(void);
int dns_test(void);
bool repeating_timer_callback(struct repeating_timer *t);

wiz_NetInfo net_info = {
    .mac = {0x00, 0x08, 0xdc, 0x16, 0xed, 0x2e},
    .ip = {192, 168, 1, 10},
    .sn = {255, 255, 255, 0},
    .gw = {192, 168, 1, 1},
    .dns = {8, 8, 8, 8},
    .dhcp = NETINFO_STATIC};
wiz_NetInfo get_info;
static uint8_t ethernet_buf[ETHERNET_BUF_MAX_SIZE] = {0,};
uint8_t DNS_2nd[4] = {114,114,114,114};
uint8_t Domain_name[] = "www.baidu.com";
uint8_t Domain_IP[4] = {0,};
uint8_t g_msec_cnt = 0;

我们简单看下声明的这三个函数的具体实现,如下所示:network_init是配置网络信息并用串口打印回显方便观察;dns_test通过调用DNS_run根据其返回的状态做出相应处理,如果dns服务器解析超时或失败就用备用的,如果解析成功就打印出域名解析后的对应ip;然后把定时器处理程序放在定时器回调里,定时1秒,每秒调用一次。

void network_init(void)
{
    uint8_t temp;
    wizchip_initialize();
    printf("W6100 dns test example.\r\n");
    sleep_ms(2000);
     /* Determine the network lock register status */
    if(!ctlwizchip(SYS_NET_LOCK, &temp))
    {   
        printf("unlock.\n");
        NETUNLOCK();
    }
    wizchip_setnetinfo(&static_info);
    print_net_info(&net_info);
    sleep_ms(2000);
}

int dns_test(void)
{
    int ret;
    printf("\r\n===== DNS Client Example =====\r\n");
    printf("> DNS 1st: %d.%d.%d.%d\r\n",net_info.dns[0],net_info.dns[1],net_info.dns[2],net_info.dns[3]);
    printf("> DNS 2nd: %d.%d.%d.%d\r\n",DNS_2nd[0],DNS_2nd[1],DNS_2nd[2],DNS_2nd[3]);
    printf("==============================\r\n");
    printf("> Example Domain Name : %s\r\n",Domain_name);

    if((ret = DNS_run(SOCKET_ID, net_info.dns, Domain_name, Domain_IP, AS_IPV4)) > 0)
    {
        printf("> 1st DNS Reponsed\r\n");
    }
    else if((ret != -1) && ((ret = DNS_run(SOCKET_ID, DNS_2nd, Domain_name, Domain_IP, AS_IPV4)) > 0))
    {
        printf("> 2nd DNS Responsed\r\n");
    }
    else if(ret == -1)
    {
        printf("> MAX_DOMAIN_NAME is too small. Should be redefined it. \r\n");
    }
    else
    {
        printf("> DNS Failed\r\n");
    }
    if(ret > 0)
    {
        printf("> Translated %s to %d.%d.%d.%d\r\n",Domain_name,Domain_IP[0],Domain_IP[1],Domain_IP[2],Domain_IP[3]);
        return 1;
    }
    return 0;
}

/* Timer */
bool repeating_timer_callback(struct repeating_timer *t)
{
    DNS_time_handler();
    return true;
}

 主程序就是先初始化所有配置,启动定时器,然后运行dns即可,成功就停止(进入while死循环),不成功就继续执行。

2.编译烧录

编译后,打开build下对应的文件夹里找到uf2文件;然后开发板按下BOOTSEL键复位上电进入程序下载模式,此时我们的电脑会检测到一个名为RPI-RP2的u盘,把uf2文件拖入即可完成烧录,如下所示:

 3.测试现象

程序下载到我们的开发板后,打开串口监视器,波特率默认为115200,我们可以看到通过dns我们成功解析出了百度(www.baidu.com)的IP地址。如下图所示:

W6100-EVB-PICO做DNS Client进行域名解析(四)_第1张图片

 相关代码链接 

W6100-EVB-PICO相关例程https://gitee.com/wiznet-hk/example-of-w6100-evb-pico.git

你可能感兴趣的:(W6100以太网芯片,WIZnet,W6100-EVB-PICO,树莓派pico,C,SDK,嵌入式设备入网教程)