超文本傳輸協(xié)議(HTTP)是一種通信協(xié)議,它允許將超文本標(biāo)記語(yǔ)言文檔從Web服務(wù)器傳送到客戶端瀏覽器; HTTP是一個(gè)屬于應(yīng)用層面向?qū)ο蟮膮f(xié)議,由于其簡(jiǎn)捷、決速的方式,適用于分布式超媒體信息系統(tǒng)
超文本是包含有超鏈接和各種多媒體元素標(biāo)記的文本。 這些超文本文件彼此鏈接,形成網(wǎng)狀(Web),因此又被稱為網(wǎng)頁(yè)(Web Page)。 這些鏈接使用URL表示。 最常見的超文本格式是超文本標(biāo)記語(yǔ)言HTML
URL即統(tǒng)一資源定位符(Uniform Resource Locator),用來唯一地標(biāo)識(shí)萬(wàn)維網(wǎng)中的某一個(gè)文檔。 URL由協(xié)議、主機(jī)和端口(默認(rèn)為80)以及文件名三部分構(gòu)成。 如:
HTTP工作原理如下圖示
HTTP報(bào)文結(jié)構(gòu):
請(qǐng)求報(bào)文:即從客戶端(瀏覽器)向Web服務(wù)器發(fā)送的請(qǐng)求報(bào)文。 報(bào)文的所有字段都是ASCII碼
響應(yīng)報(bào)文:即從Web服務(wù)器到客戶端(瀏覽器)的應(yīng)答。 報(bào)文的所有字段都是ASCII碼
請(qǐng)求方法:請(qǐng)求報(bào)文中的方法,是對(duì)所請(qǐng)求對(duì)象所進(jìn)行的操作,也就是一些命令
下面將介紹如何使用 ESP8266 SDK開發(fā) HTTP通信的客戶端和服務(wù)端
1. HTTP Client 編程
HTTP Client 要實(shí)現(xiàn)的功能:
HTTP Client 任務(wù)流程如下示:
實(shí)現(xiàn)步驟如下:
在ESP8266_RTOS_SDK目錄下新建 httpclient文件夾,把 station實(shí)驗(yàn)中的 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()函數(shù)下添加如下代碼
#define SSID "Hotspot" //ESP8266要加入的無線網(wǎng)
#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,打開串口助手,即可接收到百度服務(wù)器返回的數(shù)據(jù)
2. HTTP Server 編程
HTTP Server 要實(shí)現(xiàn)的功能:
- 模擬httpserver等待網(wǎng)頁(yè)訪問
- PC訪問網(wǎng)頁(yè),查看網(wǎng)頁(yè)信息
HTTP Server 任務(wù)流程如下示:
實(shí)現(xiàn)步驟如下:
在ESP8266_RTOS_SDK目錄下新建 httpserver文件夾,把 station實(shí)驗(yàn)中的 station目錄下所有文件拷貝到該文件夾中
在 user目錄下新建 httpserver.c文件,并添加如下代碼
/*******************httpserver.c******************************************/
#defineSERVERADDR"192.168.191.29"//esp8266連上WiFi后的IP地址
#define SERVERPORT 8000
//ATaskHttpServer任務(wù)
constchar*DefaultPage=
""
""
""
"歡迎進(jìn)入html世界"
""
""
"歡迎關(guān)注微信公眾號(hào):andyxi_linux"
""
"";
// 發(fā)送200 ok報(bào)頭
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 任務(wù)
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()函數(shù)下添加如下代碼
#define SSID "Hotspot" //PC端和ESP8266要加入的無線網(wǎng)
#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在同一個(gè)網(wǎng)絡(luò)中,模組復(fù)位后,在瀏覽器中輸入 ESP8266的 IP地址(192.168.191.29),即可訪問到 ESP8266返回的網(wǎng)頁(yè)信息(如下圖示)
-
通信協(xié)議
+關(guān)注
關(guān)注
28文章
885瀏覽量
40315 -
Web
+關(guān)注
關(guān)注
2文章
1263瀏覽量
69508 -
服務(wù)器
+關(guān)注
關(guān)注
12文章
9184瀏覽量
85490 -
編程
+關(guān)注
關(guān)注
88文章
3616瀏覽量
93763 -
ESP8266
+關(guān)注
關(guān)注
50文章
962瀏覽量
45064
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論