首页 最新 热门 推荐

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

乐鑫Esp32学习之旅14 esp32 sdk编程实现门户强制认证,连接esp32热点之后,自动强制弹出指定的登录html界面。(附带Demo)

  • 23-11-14 06:42
  • 2725
  • 8389
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开放平台,实现叮咚音响语音智能控制。
18、入门京东微联·小京鱼的控制面板H5开发,读懂vue语法,做自己的控制页面。
19、重磅开源,如何在微信小程序上ble蓝牙配网esp32,blufi的那些事!
20、一篇好文,开发过程中编译esp32固件太大,无法正常启动?教你如何自定义分区表partitions.csv。


文章目录

  • 一、前言
  • 二、什么是 门户强制认证
  • 二、实现过程
  • 三、调试心得
          • 本博文代码下载(不再需要积分下载,免费给大家使用)
    • 另外,不要把我的博客作为学习标准,我的只是笔记,难有疏忽之处,如果有,请指出来,也欢迎留言哈!

一、前言


     最近在做esp32 wifi 配网用热点实现,已经成功实现了;效果也就是大家说的:连接esp32的热点之后,自动弹出登录输入路由器账号密码的界面;

     说真的,我不想把这个博文分享出来,这个是我有道云笔记里面的一篇,因为你写的不好嘛,有人会说你讲解真费劲;发现你不是原创嘛,之后说你抄袭别人;发现你还收费卖代码?就大发雷霆地网上说你“不要脸”;卧槽,我本人还真遇到这样的事情! 之后,我在我们的qq群的 fastAdmin 开源创始人说:我们开源项目也被喷! 我突然明白,什么是网络暴力!

     生活本来就难就忙,我不想理会杠精,自己写些分享博文,某些人爱看不看!

     这篇是理论篇,下篇再分享输入账号密码:实现门户强制认证,连接esp32热点之后,自动强制弹出指定的html界面。


     特别在此 感谢安信可科技@张工 的技术支持;


  • 下面演示下效果(建议全屏观看):
    • 1、不管是 iPhone 手机还是Android手机,搜索热点 “自动弹出界面” ;
    • 2、连接成功之后,自动弹出一个html界面,这个html界面是自定义的;
    • 3、如果苹果手机发现不会弹出,可能存在你把自动登录 取消了‘

·


二、什么是 门户强制认证


     这个,我也是从网上了解到的这个名词,其中实现在 esp8266 的,传送门 ,大概总结了下:

     开启热点的esp32要开启 udp 服务器和 tcp服务器,而 我上面博文也讲述了这点,有了前面的基础,我们不难发现不管是苹果手机还是Android手机,当 dns 成功之后,都会去向他们的网站去授权请求 同步网络时间等操作,如果发现返回的数据与期待的数据不对,就会认为是登录失败,会自动弹出界面;

     好比我们在某些公共场所连接wifi一样,就像我上个月在旅游时候,住的一个酒店,前台给了你房间的路由器账号密码,但是你连接之后,还是不能上网的,而是需要你输入手机号码获取验证码之后才可以上网;

     而连接之后,就会拦截强制弹出这样类似的登录界面;这样的例子是在太多了,记得学校的图书馆wifi也是这样,当学校宿舍的网线欠费了,就会弹出叫你付费的界面,那时候杠精,几个人公用一条网线哈哈!


二、实现过程


  • dns 服务器:建立无法就是一个 udp 服务器,监听 53 端口,处理数据:
static void my_dns_server(void *pvParameters)
{
    uint8_t data[128];
    int len = 0;
    struct sockaddr_in client = { 0 };
    socklen_t  client_len=sizeof(struct sockaddr_in); 
    uint32_t i = 0;
    ESP_LOGI(TAG,"DNS server start ...");
    int sock = create_udp_socket(53);
    if (sock < 0) {
        ESP_LOGE(TAG,"Failed to create IPv4 multicast socket");
    }
    while(1)
    {
        len=recvfrom(sock,data,100,0,(struct sockaddr *)&client,&client_len); //阻塞式
        if((len < 0) || ( len > 100))
        {
            ESP_LOGE(TAG,"recvfrom error
");
            continue;
        }
        printf("DNS request:");
        for(i = 0x4; i< len;i++)
        {
            if((data[i] >= 'a' && data[i] <= 'z') || (data[i] >= 'A' && data[i] <= 'Z') ||(data[i] >= '0' && data[i] <= '9'))
                printf("%c",data[i]);
            else
                printf("_");
        }
        printf("
");
        //printf("%d
",esp_get_free_heap_size()); //打印系统可用内存
        //过滤掉一些乱糟糟的域名
        if( strstr((const char *)data+0xc,"taobao")||
            strstr((const char *)data+0xc,"qq")    || 
            strstr((const char *)data+0xc,"sogou") ||
            strstr((const char *)data+0xc,"amap")  ||
            strstr((const char *)data+0xc,"alipay")||
            strstr((const char *)data+0xc,"youku") ||
            strstr((const char *)data+0xc,"iqiyi") ||
            strstr((const char *)data+0xc,"baidu"))
        {
            continue;
        }
        data[2] |= 0x80;
        data[3] |= 0x80;
        data[7] =1;
        data[len++] =0xc0;
        data[len++] =0x0c;
        data[len++] =0x00;
        data[len++] =0x01;
        data[len++] =0x00;
        data[len++] =0x01;
        data[len++] =0x00;
        data[len++] =0x00;
        data[len++] =0x00;
        data[len++] =0x0A;
        data[len++] =0x00;
        data[len++] =0x04;
        data[len++] =192;
        data[len++] =168;
        data[len++] =4;
        data[len++] =1;
        /*打印客户端地址和端口号*/
        // inet_ntop(AF_INET,&client.sin_addr,(char *)data,sizeof(data));
        // printf("client IP is %s, port is %d
",data,ntohs(client.sin_port));
        sendto(sock,data,len,0,(struct sockaddr*)&client,client_len);
        vTaskDelay(10);
    }
    ESP_LOGE(TAG,"DNS server stop ...");
    shutdown(sock, 0);
    close(sock);
    vTaskDelete(NULL);
}
  • 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
  • 72

      tcp 服务器:这个服务器,其实就是为了处理客户端的 http 请求,注意,门户强制认证不支持 https ,所以,简简单单建立一个 tcp server 返回 html 即可!
      按照惯例,我们都是把一个 html 界面代码放在一个宏定义或者数组中返回,但是认真看乐鑫的demo,不难发现它是可以把 html 编译成bin文件的,也就是说,你标准写一个 html 界面就可以了;
      还要特别注意,自己写html界面,要在 .mk 文件加上这么一句以表示编译:

COMPONENT_EMBED_TXTFILES :=  index.html
  • 1

      然后在引用c文件这样写:

extern const uint8_t index_html_start[] asm("_binary_index_html_start");
extern const uint8_t index_html_end[]   asm("_binary_index_html_end");

//index_html_start是指针,而index_html_end - index_html_start可以得到长度
my_write(fd,index_html_start, index_html_end - index_html_start);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

      具体的 http header嘛,很简单,这样写:

static const char *HTTP_200 =   "HTTP/1.1 200 OK
"
                                "Server: lwIP/1.4.0
"
						        "Content-Type: text/html
"
						        "Connection: Keep-Alive
"
				                "Content-Length: %d 

";

static const char *HTTP_400 =   "HTTP/1.0 400 BadRequest
"
				                "Content-Length: 0
"
				                "Connection: Close
"
				                "Server: lwIP/1.4.0

";
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

三、调试心得


  • 在调试过程中还发现了这几个痛点:
    • 1、苹果手机和Android手机的浏览器内核不一样,导致某些情况下不会自动显示!这里我观察到,如果你的图片 base64 编码跟大,苹果手机不会显示。而Android手机正常显示;这里我贴下:base64 图片转换地址: http://tool.oschina.net/encrypt?type=4
    • 2、苹果手机连接wifi之后,wifi详情有个“自动登录”按钮,如果取消自动登录,也是无法自动弹出的,安卓的没这情况;
    • 3、如果发现什么情况都不能自动弹出,那么只有访问路由器的ip地址咯!默认是 192.168.4.1 。
本博文代码下载(不再需要积分下载,免费给大家使用)

https://github.com/xuhongv/StudyInEsp32/tree/master/13_captive_portal

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

  • 玩转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/102892766"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

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

分类栏目

后端 (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