esp8266 免费wifi强推广告神器(4) 发现当前WIFI下的用户数目,IP,MAC请求http信息 在用户请求跳转后跳转
需求:
1 获取当前连接客户端的HTTP请求各种信息
- 方法 get http
- 请求路径 例如 /index.html / /pic.jpg
- 请求版本 HTTP/1.0 HTTP/1.1 用于苹果WIFI连接判断,第二次请求是HTTP1.1 ,弹出认证窗口
工程组要调用了<ESP8266WebServer.h>文件

找到源码路径(无非是用户名"dongdong"替换)
C:\Users\dongdong\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\libraries\ESP8266WebServer\src

在我们的主线程里,每次有新的客户端来,都是
webServer.handleClient();
处理的。

追踪源码库

看不懂。
我们现在用的服务器库是集成了简单的http处理,首先来看一个简单的http单独的处理。
找到基本样例

void loop(void) {
MDNS.update();
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
Serial.println("");
Serial.println("New client");
// Wait for data from client to become available
while (client.connected() && !client.available()) {
delay(1);
}
// Read the first line of HTTP request
String req = client.readStringUntil('\r');
// First line of HTTP request looks like "GET /path HTTP/1.1"
// Retrieve the "/path" part by finding the spaces
int addr_start = req.indexOf(' ');
int addr_end = req.indexOf(' ', addr_start + 1);
if (addr_start == -1 || addr_end == -1) {
Serial.print("Invalid request: ");
Serial.println(req);
return;
}
req = req.substring(addr_start + 1, addr_end);
Serial.print("Request: ");
Serial.println(req);
client.flush();
String s;
if (req == "/") {
IPAddress ip = WiFi.localIP();
String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>Hello from ESP8266 at ";
s += ipStr;
s += "</html>\r\n\r\n";
Serial.println("Sending 200");
} else {
s = "HTTP/1.1 404 Not Found\r\n\r\n";
Serial.println("Sending 404");
}
client.print(s);
Serial.println("Done with client");
}
对比这个源码
要在 client.connected() && !client.available()之后进行接收数据
String req = client.readStringUntil('\r');
读取http请求信息第一行,里面包含了我们需要的三个参数
GET /path HTTP/1.1
对应到<ESP8266WebServer.h>集成度更高的源码

解析请求参数的 _parseRequest函数单独封装
在同级文件夹

再单独的http解析例程里的代码是这样的,要在对应web库里面找到对应的
// First line of HTTP request looks like "GET /path HTTP/1.1"
// Retrieve the "/path" part by finding the spaces
int addr_start = req.indexOf(' ');
int addr_end = req.indexOf(' ', addr_start + 1);
if (addr_start == -1 || addr_end == -1) {
Serial.print("Invalid request: ");
Serial.println(req);
return;
}
req = req.substring(addr_start + 1, addr_end);
Serial.print("Request: ");
Serial.println(req);
对应到web库
原来的库留有http版本的参数 但是 1.1版本 一直输出 1,截取的不完整,我们需要自己截取

人为添加一个变量requestVersion,首先头文件声明变量存在,一定要放在public区域(138行),否则会因为权限不能调用输出这个变量
打开头文件,在138行添加 String requestVersion;


然后给这个参数赋值存版本信息
动作在源代码


最后在我们的程序里调用输出
在苹果手机请求认证触发的函数里面
执行输出,并用来判断是不是第二次请求认证(这一次需要把认证界面弹出来)

我的web类定义
ESP8266WebServer webServer(80);
所以对应是 webServer(类).requestVersion(类里面我们自己加的参数)
Serial.print("_currentVersion:");Serial.println(webServer.requestVersion);
连接上esp8266wifi,打开游览器访问
http://captive.apple.com/hotspot-detect.html
(模拟苹果自动请求认证上网)
请求触发ESP8266执行我们刚才那个函数,在里面打印当前的http参数

串口输出

这样根据IP判断是不是同一个苹果设备,统计次数,建立一个路由表,统计最近4个人(最多只能同时4个),单纯IP判断会有问题,万一丢了一次,三次回复给手机的认证顺序就乱了。
所以根据 HTTP的版本 1.1 确定这是第二次的访问,这一次就要把认证界面返回给手机网页,之后第三次就要返回success页面。
根据这个流程,就可以在源码里输出自己要的信息。
2 获取客户端的IP ,端口,MAC,总连接数目

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
extern "C" {
#include<user_interface.h>
}
/* configuration wifi */
const char *ssid = "COblaster";
ESP8266WebServer server(80);
bool wifiopen=1;
String HtmlCreat(String addstring){
String newhtml=String()+"<!DOCTYPE html>\r\n "
+ "<html lang=\"zh-CN\"> \r\n"
+" <meta http-equiv='Content-type' content='text/html; charset=utf-8'>\r\n"
+"<title> </title>\r\n"
+"</head>\r\n"
+"<body>\r\n"
+addstring
//+"<p> 显示一条文字信息! </p>\r\n"
//+"<script type=\"text/javascript\">\r\n" + " window.location = \"http://192.168.4.1/\";\r\n"+ "</script>\r\n"
+"</body>\r\n"
+"</html>";
return newhtml;
}
void handleRoot() {
String newhtml=String()+"<script type=\"text/javascript\">\r\n" + "setTimeout(\"alert("")\", 3000);" +" window.location = \"http://www.baidu.com/\";\r\n"+ "</script>\r\n";
server.send(200, "text/html",HtmlCreat(newhtml) );
// server.send(200, "text/html", "<h1>You are connected</h1>");
String addy = server.client().remoteIP().toString();
Serial.println(addy);
Serial.println(server.client().remotePort(),1);
Serial.println("stopAll");
server.client().stop();
WiFi.softAPdisconnect(1);
wifiopen=0;
}
void setup() {
delay(1000);
Serial.begin(115200);
Serial.println();
Serial.print("Configuring access point...");
WiFi.softAP(ssid);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.on("/", handleRoot);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient();
delay(5000);
client_status();
delay(4000);
}
void client_status() {
unsigned char number_client;
struct station_info *stat_info;
struct ip_addr *IPaddress;
IPAddress address;
int i=1;
//number_client= wifi_softap_get_station_num();
String numbers_client=String( wifi_softap_get_station_num());
stat_info = wifi_softap_get_station_info();
Serial.print(" Total connected_client are = ");
Serial.println(number_client);
if(numbers_client.toInt()==0){ if(wifiopen==0){Serial.println(" go"); wifiopen=1; WiFi.softAP(ssid);}}
while (stat_info != NULL) {
//IPaddress = &stat_info->ip;
//address = IPaddress->addr;
Serial.print("client= ");
Serial.print(i);
Serial.print(" ip adress is = ");
Serial.print((stat_info->ip.addr));
Serial.print(" with mac adress is = ");
Serial.print(stat_info->bssid[0],HEX);
Serial.print(stat_info->bssid[1],HEX);
Serial.print(stat_info->bssid[2],HEX);
Serial.print(stat_info->bssid[3],HEX);
Serial.print(stat_info->bssid[4],HEX);
Serial.print(stat_info->bssid[5],HEX);
stat_info = STAILQ_NEXT(stat_info, next);
i++;
Serial.println();
}
delay(500);
}
esp8266 免费wifi强推广告神器(4) 发现当前WIFI下的用户数目,IP,MAC请求http信息 在用户请求跳转后跳转的更多相关文章
- esp8266 免费wifi强推广告神器(0) 项目介绍
某宝产品 WIFI SSID广告终端路由推广宝 简单来说,手机连接免费wifi,自动弹出广告页面,有二维码和电话,点击电话直接打电话给商家客服,用户点击链接跳转到商家网页. 同时存在设置页面,使用者可 ...
- WiFi广告强推的基本技术原理和一些相关问题
WiFi推原理(转) 本文地址:http://jb.tongxinmao.com/Article/Detail/id/412 WiFi广告强推的基本技术原理和一些相关问题 WiFi广告推送原理就是利用 ...
- 在Git上如何强推代码规范
引言 最近参加了“前端规范制定topic”小组,小组成员一起制定了html.css.js.es6.vue和react等规范,但规范制定好了怎么进行推广去强制执行呢,已知我们的项目都是用git做管理的, ...
- ESP8266 HTTP 项目(2)HTTP网页修改WIFI连接,上电自动连接上次的WIFI。
网页 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf ...
- 为免费app嵌入Admob广告
为免费app嵌入Admob广告,进而获得广告收入. 1.http://www.admob.com/注册一个帐号, 添加Add Mobile Site/app,输入相关信息后,提交完成, 下载Andro ...
- git 强推本地分支覆盖远程分支
git 强推本地分支覆盖远程分支git push origin 分支名 --force
- PyTorch Hub发布!一行代码调用最潮模型,图灵奖得主强推
为了调用各种经典机器学习模型,今后你不必重复造轮子了. 刚刚,Facebook宣布推出PyTorch Hub,一个包含计算机视觉.自然语言处理领域的诸多经典模型的聚合中心,让你调用起来更方便. 有多方 ...
- 微信硬件平台(八) 3 ESP8266向微信服务器请求设备绑定的用户
https://api.weixin.qq.com/device/get_openid?access_token=自己申请微信token&device_type=gh_e93c1b3098b9 ...
- 為什麼我的手機連Wi-Fi速度總是卡在75Mbps?Wi-Fi速度解惑~帶你一次看懂!
正文字体大小:大 中 小 為什麼我的手機連Wi-Fi速度總是卡在75Mbps?Wi-Fi速度解惑-帶你一次看懂! (2017-02-21 10:57:48) 转载▼ 标签: wi-fi速度 手機wi- ...
随机推荐
- C语言用regcomp、regexec、regfree和regerror函数实现正则表达式校验
前言 首先,祝大家国庆假期玩的嗨皮!可能有的人已经在回家的路上了,是不是都看不到我的真挚祝福了? C语言对于一些东西的封装比较少,比如正则表达式,但速度快一直使它立于不败之地,今天就要介绍如何用C封装 ...
- MongoDB添加secondary节点的两种方法
前段时间维护的一个事业群的其中一条业务线的开发找到运维,提出来了一个MongoDB的优化问题,那段时间MongoDB正在从op管理移交给db进行维护,整个部门都对MongoDB的运维经验缺乏,Mong ...
- 【Java基础】【14正则表达式&常用工具类】
14.01_常见对象(正则表达式的概述和简单使用) A:正则表达式 是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串.其实就是一种规则.有自己特殊的应用. 作用:比如注册邮箱,邮箱有 ...
- 认识Js中的二进制数据
Blob 在项目中涉及到要对html原生的audio组件进行样式复写,因此需要重新实现audio的一些功能,比如下载.实现一个下载大致的思路是服务端返回一段音频的二进制数据,客户端将其存放在Blob中 ...
- 第一个Mybatis程序示例 Mybatis简介(一)
在JDBC小结中(可以参阅本人JDBC系列文章),介绍到了ORM,其中Mybatis就是一个不错的ORM框架 MyBatis由iBatis演化而来 iBATIS一词来源于“internet”和“aba ...
- haproxy使用演示--技术流ken
haproxy简介 HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.基于合理的配置及优化,完全可以实现单机支持数 以万计的并 ...
- C# IQueryable和IEnumerable的区别
在使用EF查询数据的时候,我们常用的查询数据方式有linq to sql,linq to object, 查询返回的结果有两种类型:IQueryable.IEnumerable,两者内部的处理机制是完 ...
- 【EF】CodeFirst Fluent API使用记录
我们在使用EF CodeFirst 模式生成数据库的时候进行表的代码映射关系可以采用注解模式和Fluent API模式.这里就是记录一下使用Fluent API进行表关系映射的方法. 注解模式: 回顾 ...
- Phpstudy升级到Mysql8
之前一直用的mysql5.5,最近发现Mysql8更新了很多新特性以及查询效率的提升,觉得很有必要更新下开发版本,好,废话不多说: 1.下载安装包,下载地址:mysql8.0 .如果你想要下载其它版 ...
- WEB前端开发记录PS常见操作
1.相邻2个层合并的快捷键方法:先选择上面的一个层,再按ctrl+e. 2.合并一个组内的多个层或组:在该组单击右键,选择“转换为智能对象”,然后可对其进行其它操作,比如:截取该组的为一张图片:ctr ...