首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

乐鑫Esp32学习之旅13 esp32 内置 dns 服务器,无需外网访问域名返回指定网页。(附带Demo)

  • 23-11-14 06:42
  • 2911
  • 11185
blog.csdn.net

  • 本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途。如有不对之处,请留言,本人及时更改。

1、 爬坑学习新旅程,虚拟机搭建esp32开发环境,打印 “Hellow World”。
2、 巧用eclipes编辑器,官方教程在在Windows下搭建esp32开发环境,打印 “Hellow World”。
3、 认识基本esp32的GPIO接口,开始点亮您的第一盏 LED和中断回调实现按键功能 。
4、体会esp32的强大的定时器功能, 实现定时2s闪烁一盏LED灯。
5、接触实践esp32的pwm宽度脉冲功能, 实现呼吸效果闪烁一盏LED灯。
6、smartConfig和微信airKiss在esp32的实现,一键配网轻松快捷连接路由器。
7、利用GPIO中断做一个按键的短按和长按的回调事件,再也无须担心触发源。
8、esp32上实现本地 UDP 客户端和服务端角色,在局域网内实现通讯。
9、esp32上实现本地 TCP 客户端和服务端角色,可断线重连原路返回数据。
10、乐鑫esp32 SDK编程利用rmt驱动ws2812七彩灯,实现彩虹渐变效果。
11、入门 乐鑫esp-adf 音频框架开发,esp32造一个蓝牙耳机,实现切换歌曲,获取歌曲信息等功能。
12、开源一个微信公众号airkiss配网esp32以及局域网发现功能的工程,分享一个airkiss配网小工具。
13、esp32 内置 dns 服务器,无需外网访问域名返回指定网页。
14、esp32 sdk编程实现门户强制认证,连接esp32热点之后,自动强制弹出指定的登录界面。
15、认识本地离线语音唤醒识别框架 esp-skainet ,实现较低成本的硬件语音本地识别控制。
16、学习本地语音唤醒离线识别框架 esp-skainet ,如何修改唤醒词? 如何自定义命令词?如何做意图动作?
17、全网首发,乐鑫esp32 sdk直连京东微联·小京鱼 · IoT开放平台,实现叮咚音响语音智能控制。


文章目录

  • 一、前言
  • 二、实现原理和流程
    • 2.1 原理
    • 2.2 流程
  • 三、代码
      • 3.1 DNS服务器
      • 3.2 server服务器
  • 四、其他
          • 源码学习与总结,参考来自:
          • 本博文代码下载(不再需要积分下载,免费给大家使用)
    • 另外,不要把我的博客作为学习标准,我的只是笔记,难有疏忽之处,如果有,请指出来,也欢迎留言哈!

在这里插入图片描述

一、前言


     在物联网搞了这么多的玩意,包括服务器、嵌入式、小程序、Android等,我的确是不会 ‘精通’ 一门技术,看到网上很多招聘信息,嵌入式开发的工资较低的,其中 Android和服务器这边薪酬较高,我在想,如果我哪一天去面试新公司,我该面试哪个职位?真不知道。。。

     随着年龄成长,成家立业的想法迫使我压力很大,也许你到了这30未至,未成家的阶段,和我一样的焦虑。好吧!说到底,还是工作与生活,明年准备换个公司吧。希望身边都是优秀的人,待遇薪酬也高一点!

     说了这么多,开始正题:如何没有外网的情况下,实现访问域名返回指定的网页!

二、实现原理和流程


     也许你会问,这个无需外网访问域名就可以返回 html 有啥用啊?这个问题提的好,我们可以在平时的生活中也遇到这样的事情:第一次买的路由器,需要配置 网络运营商的 账号密码,我们一般是 浏览器地址栏输入“192.168.xx.xx” ,而有的是 访问 “www.xxx.com” 这样的域名。你觉得哪个好?我觉得域名比较好;

  • 第一:体现你的品牌,比如小米的 mi.wifi.com 这样的域名;
  • 第二:主机名便于人的记忆,而IP地址便于计算机网络设备的处理;

2.1 原理

     因为没外网访问域名,所以需要内置一个 dns 服务器,毕竟我们平时访问的域名,都是先经过 dns 解析得到 ip 地址再访问 ip 地址的,就像前几天的国内码云域名被阿里云冻结事件,不难分析出,如果你的域名无法被解析,那么客户端无法访问;

     有一个dns服务器还是不够的,因为你即使得到 ip 地址,客户端还会去 get 请求这个域名,所以,你还得具备一个 server 服务器,而 server 服务器是基于 tcp 的,所以你得做一个 tcp 服务器 http 格式,端口号是 80 ;

     而DNS走的是UDP协议,使用的端口号是53,所以不管收到什么,都回复!

     dns服务器建立参考:传送门


2.2 流程


     第一步自己开启热点,这时候你就是相当于一个没外网的一个路由器啦!之后开启 dns 服务器,再开启 tcp 服务器,等待客户端 dns 解析请求和 http 请求 !


在这里插入图片描述

三、代码


  • 所有代码,都在博文下面获取!

3.1 DNS服务器

  • 得到一个 dns 解析请求:
void get_dns_request(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
    printf("get the massage from sat
");
    struct dns_ans_hdr hdr;
    upcb1 = upcb;
    addr1 = addr;
    port1 = port;
    if (p->tot_len < (SIZEOF_DNSANS_HDR + SIZEOF_DNSANS_HDRQUE))
    {
        printf("dns_recv: pbuf too small
");
        /* 非dns请求 */
    }
    else
    {
        pbuf_copy_partial(p, &hdr, SIZEOF_DNSANS_HDR, 0);
        txid = ntohs(hdr.id);
        nquestions = ntohs(hdr.numquestions);
    }
    pbuf_free(p); //check this
    dns_server_send();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

  • 返回 dns 解析请求给客户端,下面我是指为一个域名,宏定义的 TABLENAME 为: www.xuhong.com,这样的格式!
void dns_server_send(void)
{
    struct pbuf *rp = NULL;
    struct dns_ans_hdr hdr;
    struct dns_ans_ans qry;
    uint8_t n;
    uint16_t query_idx, copy_len;
    const char *hostname, *hostname_part;
    struct dns_table_entry dns_server_table = {
        .txid = DNS_SERVER_ID,
        .flags = DNS_SERVER_FLAGS,
        .numque = DNS_SERVER_NUMQUE,
        .ansrrs = DNS_SERVER_ANSRRS,
        .autrrs = DNS_SERVER_AUTRRS,
        .addrrs = DNS_SERVER_ADDRRS,
        .name = {0},
        .type = DNS_SERVER_TYPE,
        .class = DNS_SERVER_CLASS,
        .poiname = DNS_POINAME,
        .anstype = DNS_SERVER_ANSTYPE,
        .anstypee = DNS_SERVER_ANSTYPEE,
        .datalen = DNS_SERVER_DATALEN,
        .anstime = DNS_SERVER_ANSTIME,
        .adress = DNS_SERVER_ADRESS};
    strcpy(dns_server_table.name, TABLENAME); // TABLENAME是我指定的域名
    struct dns_table_entry *entry = &dns_server_table;
    rp = pbuf_alloc(PBUF_TRANSPORT, 51, PBUF_RAM);
    if (rp != NULL)
    {
        memset(&hdr, 0, SIZEOF_DNSANS_HDR);
        /* fill dns_ans header */
        hdr.id = htons(txid);
        hdr.flag = htons(entry->flags);
        hdr.numquestions = htons(entry->numque);
        hdr.numanswers = htons(entry->ansrrs);
        hdr.numauthrr = htons(entry->autrrs);
        hdr.numextrarr = htons(entry->addrrs);
        pbuf_take(rp, &hdr, SIZEOF_DNSANS_HDR);
        /* convert hostname into suitable query format. */
        hostname = entry->name;
        --hostname;
        query_idx = SIZEOF_DNSANS_HDR;
        do
        {
            ++hostname;
            hostname_part = hostname;
            for (n = 0; *hostname != '.' && *hostname != 0; ++hostname)
            {
                ++n;
            }
            copy_len = (u16_t)(hostname - hostname_part);
            pbuf_put_at(rp, query_idx, n);
            pbuf_take_at(rp, hostname_part, copy_len, query_idx + 1);
            query_idx += n + 1;
        } while (*hostname != 0);
        pbuf_put_at(rp, query_idx, 0);
        query_idx++;
        /* fill dns ans */
        qry.typ = htons(entry->type);
        qry.cls = htons(entry->class);
        qry.point = htons(entry->poiname);
        qry.antyp = htons(entry->anstype);
        qry.antypp = htons(entry->anstypee);
        qry.len = htons(entry->datalen);
        qry.time = htonl(entry->anstime);
        qry.addr = htonl(entry->adress);
        pbuf_take_at(rp, &qry, SIZEOF_DNSANS_HDRQUE, query_idx);
        udp_sendto(upcb1, rp, addr1, port1);
        free(rp);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

3.2 server服务器

  • 下面代码演示了如何作为一个 http 格式返回给客户端,其中 http_html_hdr 是头部 header ,http_index_hml 是body 部分,部分浏览器可能头部还需要添加 Content-Length 作为返回body长度才会正常显示,这个您自己添加吧!我就不加了!
  • 如果你要修改返回的内容,可以修改下面的 http_index_hml;
const static char http_html_hdr[] =
    "HTTP/1.1 200 OK
Content-type: text/html

";
const static char http_index_hml[] = ""
      "
"
      "
"
      "  
"
      "  
"
      "HELLO ESP32
"
      "
"
      "
"
      "

Hello World, from ESP32!

"
" " " "; static void web_http_server(struct netconn *conn) { struct netbuf *inputbuf; char *buf; u16_t buflen; err_t err; err = netconn_recv(conn, &inputbuf); if (err == ERR_OK) { netbuf_data(inputbuf, (void**)&buf, &buflen); printf("the received data: %s ",buf); /* Judge if this is an HTTP GET command */ if (buflen >= 5 && buf[0] == 'G' && buf[1] == 'E' && buf[2] == 'T' && buf[3] == ' ' && buf[4] == '/' ) { netconn_write(conn, http_html_hdr, sizeof(http_html_hdr)-1, NETCONN_NOCOPY); netconn_write(conn, http_index_hml, sizeof(http_index_hml)-1, NETCONN_NOCOPY); } else { netconn_write(conn, http_index_hml, sizeof(http_index_hml)-1, NETCONN_NOCOPY); } } } netconn_close(conn); netbuf_delete(inputbuf); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

四、其他


  • 代码编译成功之后,手机连接热点 XUHONG-DNS , 密码是 12345678 ,然后浏览器访问 www.xuhong.com 即可看到效果!
源码学习与总结,参考来自:
  • 强制门户认证:https://www.jianshu.com/p/0293e1a30b89
  • 乐鑫:https://github.com/WeldonWangwang/

本博文代码下载(不再需要积分下载,免费给大家使用)

https://github.com/xuhongv/StudyInEsp32/tree/master/12_dns_server

另外,不要把我的博客作为学习标准,我的只是笔记,难有疏忽之处,如果有,请指出来,也欢迎留言哈!

  • 玩转esp8266带你飞、加群付费QQ群,不喜的朋友勿喷勿加:434878850
  • esp8266源代码学习汇总(持续更新,欢迎star):https://github.com/xuhongv/StudyInEsp8266
  • esp32源代码学习汇总(持续更新,欢迎star):https://github.com/xuhongv/StudyInEsp32
  • 关注下面微信公众号二维码,干货多多,第一时间推送!
注:本文转载自blog.csdn.net的半颗心脏的文章"https://blog.csdn.net/xh870189248/article/details/102805659"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top