上一篇我们把TCP通信讲完了,这一讲我们讲一下8266的http通信,简简单单的访问下百度网址("http://www.baidu.com"),试试百度服务器会不会给我们回复数据(* ̄︶ ̄)。
1、什么是HTTP
它的含义如下图:
一般的URL其实不需要这么全,只要有域名就可以了,
例如http://www.baidu.com
2、esp8266 HTTP请求程序的设计
首先我们将百度网址的URL解析出服务器IP和端口号,通过IP和端口号与百度服务器建立TCP连接,然后发送HTTP请求头,看是否能收到服务器的数据。程序流程我也画了张图,如下:
程序编写步骤如下:
解析URL(获取域名、端口和文件名) |
使用espconn_gethostbyname函数获取服务器IP地址 |
建立TCP连接服务器 |
发送HTTP请求数据包 |
串口打印收到服务器的数据 |
编程指南中对espconn_gethostbyname介绍如下图:
3、程序实现
8266连接路由器的程序就不贴了,在下面这篇文章中已经讲了,链接如下:
连接成功后,就可以解析URL并获取百度服务器IP了。
解析URL的函数如下:
void ICACHE_FLASH_ATTR syp_Http_Parse_Request_Url(char *URL,char* host,char *file_name,unsigned short *port){
char *Pa_host;
char *Pb_file_name;
char *Pc_port;
memset(host,0,sizeof(host));
memset(file_name,0,sizeof(file_name));
||默认端口为80
*port = 80;
if(NULL == URL){
return;
}
||获取主机名
Pa_host = URL;
if(!strncmp(Pa_host,"http://",strlen("http://"))){
Pa_host = URL + strlen("http://");
}else if(!strncmp(Pa_host,"https://",strlen("https://"))){
Pa_host = URL + strlen("https://");
}
Pb_file_name = strchr(Pa_host,'/');
if(Pb_file_name){
||获取主机名www.baidu.com
memcpy(host,Pa_host,strlen(Pa_host) - strlen(Pb_file_name));
host[strlen(Pa_host) - strlen(Pb_file_name)] = 0;
if(Pb_file_name + 1){
||获取文件名index.php
memcpy(file_name,Pb_file_name + 1,strlen(Pb_file_name + 1));
file_name[strlen(Pb_file_name + 1)] = 0;
}
}else{
||获取主机名www.baidu.com
memcpy(host,Pa_host,strlen(Pa_host));
host[strlen(Pa_host)] = 0;
}
||获取端口号
Pc_port = strchr(host,':');
if( Pc_port ){
*port = atoi(Pc_port + 1);
}
}
获取百度服务器IP地址的函数如下:
void ICACHE_FLASH_ATTR syp_Http_Read_File(char * URL){
ip_addr_t addr;
||解析出host 和 端口号
syp_Http_Parse_Request_Url(URL,host,file_name,&http_port);
||获取IP,并注册回调函数dns_found_callback_found_cb
espconn_gethostbyname(&syp_user_tcp_conn, host, &addr, dns_found_callback_found_cb);
}
在回调函数中建立TCP连接,函数如下:
void dns_found_callback_found_cb(const char *name, ip_addr_t *ipaddr, void *callback_arg){
struct ip_info info;
wifi_get_ip_info(STATION_IF, &info);
||建立TCP连接
syp_my_station_init( ipaddr, &info.ip, http_port);
}
发送HTTP数据包函数如下:
void ICACHE_FLASH_ATTR syp_user_tcp_connect_cb(void *arg) {
struct espconn *pespconn = arg;
||TCP连接成功,注册回调函数
espconn_regist_recvcb(pespconn, syp_user_tcp_recv_cb); //注册接收数据的回调函数
espconn_regist_sentcb(pespconn, syp_user_tcp_sent_cb); //注册发送数据成功的回调函数
espconn_regist_disconcb(pespconn, syp_user_tcp_discon_cb); //注册断开连接的回调函数
||发送HTTP数据包
//espconn_sent(pespconn,"我是ESP8266",strlen("我是ESP8266"));
espconn_sent(pespconn,HEAD_BAIDU,strlen(HEAD_BAIDU));
}
第一次测试发送"我是ESP8266",百度服务器居然不认识我们,哈哈哈
第二次发送HTTP请求包,成功收到百度服务器发来的数据。
测试结果如下图:
发送正确的HTTP数据包,就可以收到百度发来的数据了,一下发回好多数据,如下图:
百度一下子给我们发了好几个数据包,还有乱码。
(* ̄︶ ̄)
补充
我们给服务器发送的HTTP数据包内容如下:
"GET / HTTP/1.1\r\n
Accept-Language:zh-CN\r\n
Accept-Encoding:gzip, deflate\r\n
Host: www.baidu.com\r\n
Connection:keep-alive\r\n\r\n"
GET / HTTP/1.1意思是请求方法为GET方法,请求协议为HTTP,协议的版本为1.1
Accept-Language:zh-CN意思是支持的语言是简体中文。
Accept-Encoding:gzip, deflate意思是支持gzip压缩(我们收到的乱码可能是压缩造成的)。
Host: www.baidu.com意思访问的是主机名为百度。
Connection:keep-alive意思是告诉服务器维持长链接。
好了,今天就讲这么多,下次接着讲讲HTTP 的 GET方法。
原创不易,如果你喜欢我的公众号、觉得我 文章对你有所启发,
请务必“点赞、在看、收藏、转发”,这对我很重要,谢谢!
欢迎订阅 嵌入式小书虫