嵌入式系统与单片机|技术阅读
登录|注册

您现在的位置是:嵌入式系统与单片机 > 技术阅读 > ESP8266入门(八)HTTP通信之访问百度服务器​

ESP8266入门(八)HTTP通信之访问百度服务器​

上一篇我们把TCP通信讲完了,这一讲我们讲一下8266的http通信,简简单单的访问下百度网址("http://www.baidu.com"),试试百度服务器会不会给我们回复数据(* ̄︶ ̄)。


1、什么是HTTP


HTTP(Hyper Text Transfer Protocol)超文本传输协议,是一个简单的请求-响应协议,它通常是运行在TCP通信之上。指定客户端发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII码形式给出。HTTP通信客户端就是终端用户,服务器端就是网站。通过使用Web浏览器、网络爬虫或者其它的工具(esp8266),客户端发起一个到服务器上指定端口(默认端口为80)的HTTP请求。当我们在浏览器的地址框中输入一个URL或者单击一个超链接时,URL就确定了要浏览的网络地址。浏览器通过超文本传输协议(HTTP),将Web服务器上的网页代码提取出来,并翻译成网页。因此,在我们在认识HTTP之前,有必要先弄清楚URL的组成,例如:http://www.baidu.com:80/index.php。

它的含义如下图: 

一般的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数据包函数如下:

#define HEAD_BAIDU "GET / HTTP/1.1\r\nAccept-Language:zh-CN\r\nAccept-Encoding:gzip, deflate\r\nHost: www.baidu.com\r\nConnection:keep-alive\r\n\r\n"
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\nAccept-Language:zh-CN\r\nAccept-Encoding:gzip, deflate\r\nHost: www.baidu.com\r\nConnection: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方法。


原创不易,如果你喜欢我的公众号、觉得我 文章对你有所启发,

请务必“点赞、在看、收藏、转发”,这对我很重要,谢谢!

欢迎订阅    嵌入式小书虫