ESP8266模组的HTTP编程

描述

ESP8266 模组的 HTTP 编程

超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言文档从Web服务器传送到客户端浏览器; HTTP是一个属于应用层面向对象的协议,由于其简捷、决速的方式,适用于分布式超媒体信息系统

超文本是包含有超链接和各种多媒体元素标记的文本。 这些超文本文件彼此链接,形成网状(Web),因此又被称为网页(Web Page)。 这些链接使用URL表示。 最常见的超文本格式是超文本标记语言HTML

Web

URL即统一资源定位符(Uniform Resource Locator),用来唯一地标识万维网中的某一个文档。 URL由协议、主机和端口(默认为80)以及文件名三部分构成。 如:

Web

HTTP工作原理如下图示

Web

HTTP报文结构:

请求报文:即从客户端(浏览器)向Web服务器发送的请求报文。 报文的所有字段都是ASCII码

Web

响应报文:即从Web服务器到客户端(浏览器)的应答。 报文的所有字段都是ASCII码

Web

请求方法:请求报文中的方法,是对所请求对象所进行的操作,也就是一些命令

Web

下面将介绍如何使用 ESP8266 SDK开发 HTTP通信的客户端和服务端

1. HTTP Client 编程

HTTP Client 要实现的功能:

  • 模拟http协议,访问百度首页:
    www.baidu.com/index.html
  • 串口打印出百度返回的数据

HTTP Client 任务流程如下示:

Web

实现步骤如下:

在ESP8266_RTOS_SDK目录下新建 httpclient文件夹,把 station实验中的 station目录下所有文件拷贝到该文件夹中

在 user目录下新建 httpclient.c文件,并添加如下代码

/*******************httpclient.c************************************/
constchar GetStr[]="GET /index.html HTTP/1.1\\r\\n"
"Host: www.baidu.com\\r\\n"
"\\r\\n";
#define HTTP_RCV_LEN 50000
voidATaskHttpClient(void*pvParameters ){
int iVariableExample =0;
int fd =-1;
int NetTimeOnt =20000;
int ret;
int i;
structhostent*phostent;
structsockaddr_in ServerAddr;
char*Httpmsg;
char*ipaddr =NULL;
  STATION_STATUS StaStatus;
do{
    StaStatus =wifi_station_get_connect_status();
vTaskDelay(100);
}while(StaStatus != STATION_GOT_IP);

  fd =socket(PF_INET,SOCK_STREAM,0);
if(fd ==-1){
printf("get socket fail!\\n");
vTaskDelete(NULL);
return;
}

setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,&NetTimeOnt,sizeof(int));
  phostent =gethostbyname("www.baidu.com");
if(phostent ==NULL){
printf("get host ip fail!\\n");
vTaskDelete(NULL);
return;
}
else{
for(i =0;phostent->h_addr_list[i];i++){
      ipaddr =inet_ntoa(*(structin_addr*)(phostent->h_addr_list[i]));
if(ipaddr !=NULL){
printf("host addr is:%s\\n",  ipaddr );
break;
}
}
if(ipaddr ==NULL){
printf("error:get ip fail!\\r\\n");
vTaskDelete(NULL);
return;
}
}
memset(&ServerAddr,0,sizeof(ServerAddr));
  ServerAddr.sin_family = AF_INET;
  ServerAddr.sin_addr.s_addr =inet_addr(ipaddr);
  ServerAddr.sin_port =htons(80);
  ServerAddr.sin_len =sizeof(ServerAddr);

do{
    ret =connect(fd,(structsockaddr*)&ServerAddr,ServerAddr.sin_len);
if(ret !=0){
printf("connect is fail!\\n");
vTaskDelay(100);
}
}while(ret !=0);

  Httpmsg =zalloc(HTTP_RCV_LEN);
send(fd,GetStr,strlen(GetStr),0);
for(;;){
do{
      ret =recv(fd,Httpmsg,50000,0);
if(ret >0){
printf("%s",Httpmsg);
}else{
printf("HttpServer data is no!\\n");
}
}while(ret ==-1);
}
free(Httpmsg);
vTaskDelete(NULL);
}
//HttpClient_init 初始化
voidHttpClient_init(void){
xTaskCreate(ATaskHttpClient,"HttpClient",256,NULL,4,NULL);
}

在 include目录下新建 httpclient.h文件,并添加声明

void ATaskHttpClient(void *pvParameters);
void HttpClient_init(void);

在 user_main.c文件中的 user_init()函数下添加如下代码

#define SSID "Hotspot"	//ESP8266要加入的无线网
#define PASSWORD "88888888"
void ICACHE_FLASH_ATTR
user_init(void){
printf("SDK version:%s\\n",system_get_sdk_version());
Led_init();
wifi_set_opmode(STATION_MODE);
structstation_config*config =(structstation_config*)\\
zalloc(sizeof(structstation_config));
sprintf(config->ssid,SSID);
sprintf(config->password,PASSWORD);
wifi_station_set_config(config);
free(config);
wifi_station_set_auto_connect(TRUE);
HttpClient_init();
xTaskCreate(ATaskLed,"LED",256,NULL,2,NULL);
}

在ESP8266编译器中编译完成,烧写 bin文件到 ESP8266,打开串口助手,即可接收到百度服务器返回的数据

Web

2. HTTP Server 编程

HTTP Server 要实现的功能:

  • 模拟httpserver等待网页访问
  • PC访问网页,查看网页信息

HTTP Server 任务流程如下示:

Web

实现步骤如下:

在ESP8266_RTOS_SDK目录下新建 httpserver文件夹,把 station实验中的 station目录下所有文件拷贝到该文件夹中

在 user目录下新建 httpserver.c文件,并添加如下代码

/*******************httpserver.c******************************************/
#defineSERVERADDR"192.168.191.29"//esp8266连上WiFi后的IP地址
#define SERVERPORT 8000
//ATaskHttpServer任务
constchar*DefaultPage=
""
""
""
"欢迎进入html世界"
""
""
"欢迎关注微信公众号:andyxi_linux"
""
"";

// 发送200 ok报头
intfile_ok(int cfd,long flen){
char*send_buf =zalloc(sizeof(char)*100);
sprintf(send_buf,"HTTP/1.1 200 OK\\r\\n");
send(cfd, send_buf,strlen(send_buf),0);
sprintf(send_buf,"Connection: keep-alive\\r\\n");
send(cfd, send_buf,strlen(send_buf),0);
sprintf(send_buf,"Content-Length: %ld\\r\\n", flen);
send(cfd, send_buf,strlen(send_buf),0);
sprintf(send_buf,"Content-Type: text/html\\r\\n");
send(cfd, send_buf,strlen(send_buf),0);
sprintf(send_buf,"\\r\\n");
send(cfd, send_buf,strlen(send_buf),0);
free(send_buf);
return0;
}
//ATaskHttpServer 任务
voidATaskHttpServer(void*pvParameters ){
int iVariableExample =0;
int fd =-1;
int cfd =-1;
int NetTimeOnt =2000;
int ret;
structsockaddr_in ServerAddr;
structsockaddr ClientAddr;
socklen_t ClientAddrlen =sizeof(structsockaddr);
char*Httpmsg;
char*Sendmsg;

  STATION_STATUS StaStatus;
do{
    StaStatus =wifi_station_get_connect_status();
vTaskDelay(100);
}while(StaStatus != STATION_GOT_IP);

  fd =socket(PF_INET,SOCK_STREAM,0);
if(fd ==-1){
printf("get socket fail!\\n");
vTaskDelete(NULL);
return;
}

setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,&NetTimeOnt,sizeof(int));
memset(&ServerAddr,0,sizeof(ServerAddr));
  ServerAddr.sin_family = AF_INET;
  ServerAddr.sin_addr.s_addr = INADDR_ANY;
  ServerAddr.sin_port =htons(SERVERPORT);
  ServerAddr.sin_len =sizeof(ServerAddr);

if(bind(fd,(structsockaddr*)&ServerAddr,ServerAddr.sin_len)!=0){
printf("bind socket fail!\\n");
vTaskDelete(NULL);
return;
}

if(listen(fd,5)!=0){
printf("listen socket fail!\\n");
vTaskDelete(NULL);
return;
}
  Httpmsg =(char*)zalloc(sizeof(char)*1000);
for(;;){
    cfd =accept(fd,&ClientAddr,&ClientAddrlen);
if(cfd !=-1){
printf("HttpClient accept\\n");
      ret =recv(cfd,Httpmsg,1000,0);
if(ret >0){
printf("HttpClient recv\\n");
printf("%s\\n",Httpmsg);
file_ok(cfd,strlen(DefaultPage));
send(cfd,DefaultPage,strlen(DefaultPage),0);
}else{
printf("HttpClient data is no!\\n");
}
}
close(cfd);
}
free(Httpmsg);
vTaskDelete(NULL);
}
//HttpServer_init 初始化
voidHttpServer_init(void){
xTaskCreate(ATaskHttpServer,"HttpServer",256,NULL,4,NULL);
}

在 include目录下新建 httpserver.h文件,并添加声明

void ATaskHttcpserver( void *pvParameters );
void Httpserver_init(void);

在 user_main.c文件中的 user_init()函数下添加如下代码

#define SSID "Hotspot"	//PC端和ESP8266要加入的无线网
#define PASSWORD "88888888"	
void ICACHE_FLASH_ATTR
user_init(void){
  printf("SDK version:%s\\n", system_get_sdk_version());
  Led_init();
  wifi_set_opmode(STATION_MODE);
  struct station_config *config = (struct station_config *)\\
        zalloc(sizeof(struct station_config));
  sprintf(config->ssid,SSID);
  sprintf(config->password,PASSWORD);
  wifi_station_set_config(config);
  free(config);
  wifi_station_set_auto_connect(TRUE);    
  HttpServer_init();
  xTaskCreate(ATaskLed, "LED", 256, NULL, 2, NULL);
}

在ESP8266编译器中编译完成,烧写 bin文件到 ESP8266,确保 PC与 ESP8266在同一个网络中,模组复位后,在浏览器中输入 ESP8266的 IP地址(192.168.191.29),即可访问到 ESP8266返回的网页信息(如下图示)

Web

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分