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开放平台,实现叮咚音响语音智能控制。
在物联网搞了这么多的玩意,包括服务器、嵌入式、小程序、Android等,我的确是不会 ‘精通’ 一门技术,看到网上很多招聘信息,嵌入式开发的工资较低的,其中 Android和服务器这边薪酬较高,我在想,如果我哪一天去面试新公司,我该面试哪个职位?真不知道。。。
随着年龄成长,成家立业的想法迫使我压力很大,也许你到了这30未至,未成家的阶段,和我一样的焦虑。好吧!说到底,还是工作与生活,明年准备换个公司吧。希望身边都是优秀的人,待遇薪酬也高一点!
说了这么多,开始正题:如何没有外网的情况下,实现访问域名返回指定的网页!
也许你会问,这个无需外网访问域名就可以返回 html
有啥用啊?这个问题提的好,我们可以在平时的生活中也遇到这样的事情:第一次买的路由器,需要配置 网络运营商的 账号密码,我们一般是 浏览器地址栏输入“192.168.xx.xx
” ,而有的是 访问 “www.xxx.com
” 这样的域名。你觉得哪个好?我觉得域名比较好;
mi.wifi.com
这样的域名;因为没外网访问域名,所以需要内置一个 dns 服务器,毕竟我们平时访问的域名,都是先经过 dns 解析得到 ip 地址再访问 ip 地址的,就像前几天的国内码云域名被阿里云冻结事件,不难分析出,如果你的域名无法被解析,那么客户端无法访问;
有一个dns服务器还是不够的,因为你即使得到 ip 地址,客户端还会去 get 请求这个域名,所以,你还得具备一个 server
服务器,而 server
服务器是基于 tcp 的,所以你得做一个 tcp 服务器 http 格式,端口号是 80 ;
而DNS走的是UDP
协议,使用的端口号是53,所以不管收到什么,都回复!
dns服务器建立参考:传送门
第一步自己开启热点,这时候你就是相当于一个没外网的一个路由器啦!之后开启 dns 服务器,再开启 tcp 服务器,等待客户端 dns 解析请求和 http 请求 !
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\n");
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\n");
/* 非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();
}
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);
}
}
http_html_hdr
是头部 header ,http_index_hml
是body 部分,部分浏览器可能头部还需要添加 Content-Length
作为返回body长度才会正常显示,这个您自己添加吧!我就不加了!const static char http_html_hdr[] =
"HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n";
const static char http_index_hml[] = ""
"\n"
"\n"
" \n"
" \n"
"HELLO ESP32 \n"
"\n"
"\n"
"Hello World, from ESP32!
\n"
"\n"
"\n";
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:\n%s\n",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);
}
XUHONG-DNS
, 密码是 12345678 ,然后浏览器访问 www.xuhong.com
即可看到效果!https://github.com/xuhongv/StudyInEsp32/tree/master/12_dns_server
esp8266
带你飞、加群付费QQ
群,不喜的朋友勿喷勿加:434878850