ESP8266学习笔记(10)——官方WebServer

一、背景

6793005-c169baaf737e0c82.png

WebServer作为HTTP服务器,接收手机APP请求,配置网关接入网络。

Post请求和Get请求:


6793005-955abae7579d122c.png

二、流程

① 初始化WebServer,绑定本地端口
② 开启监听
③ 解析请求数据包
④ 回发响应数据包

三、初始化WebServer

文件所在 ESP8266_NONOS_SDK-2.1.0\IoT_Demo\user/user_webserver.c
创建TCP服务端,参考ESP8266学习笔记(5)——TCP/UDP接口使用
传入参数,本地端口80。

void ICACHE_FLASH_ATTR
user_webserver_init(uint32 port)
{
    tcp_websvr_espconn.type = ESPCONN_TCP;
    tcp_websvr_espconn.state = ESPCONN_NONE;
    tcp_websvr_espconn.proto.tcp = &esptcp;
    tcp_websvr_espconn.proto.tcp->local_port = port;                  // 设置本地端口

    espconn_regist_connectcb(&tcp_websvr_espconn, webserver_listen);  // 注册监听成功回调函数
    espconn_accept(&tcp_websvr_espconn);                              // 创建 TCP server,建立监听
}

四、开启监听

4.1 监听成功回调函数

LOCAL void ICACHE_FLASH_ATTR
webserver_listen(void *arg)
{
    struct espconn *pesp_conn = arg;

    espconn_regist_recvcb(pesp_conn, webserver_recv);      // 注册接收回调函数
    espconn_regist_reconcb(pesp_conn, webserver_recon);    // 注册发送回调函数
    espconn_regist_disconcb(pesp_conn, webserver_discon);  // 注册断连回调函数
}

4.2 接收回调函数

里面POST请求中解析JSON数据参考ESP8266学习笔记(7)——JSON接口使用

/******************************************************************************
 * FunctionName : webserver_recv
 * Description  : Processing the received data from the server
 * Parameters   : arg -- Additional argument to pass to the callback function
 *                pusrdata -- The received data (or NULL when the connection has been closed!)
 *                length -- The length of received data
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
webserver_recv(void *arg, char *pusrdata, unsigned short length)
{
    URL_Frame *pURL_Frame = NULL;
    char *pParseBuffer = NULL;
    bool parse_flag = false;                        // 解析标志
    struct espconn *ptrespconn = arg;

    /* 如果设备没有在升级 */
    if (upgrade_lock == 0)
    {
        os_printf("len:%u\n",length);
        /* 校验数据是否缺失,如果失败跳转做处理 */
        if (check_data(pusrdata, length) == false)  // ------------------下述 5.1
        {
            os_printf("goto\n");
            goto _temp_exit;
        }

         /* 校验数据长度后存储起来,开启解析标志 */
        parse_flag = save_data(pusrdata, length);   // ------------------下述 5.2

        if (parse_flag == false)
        {
            response_send(ptrespconn, false);       // ------------------下述 6.1
        }
        os_printf("pusrdata:%s\n", pusrdata);

        /* 为URL框架申请空间 */
        pURL_Frame = (URL_Frame *)os_zalloc(sizeof(URL_Frame));  // ------------------下述 5.3
        /* 解析数据,加入URL框架 */
        parse_url(precvbuffer, pURL_Frame);         // ------------------下述 5.4
        os_printf("Type:%d, Select:%s, Command:%s, Filename:%s ",
                pURL_Frame->Type,pURL_Frame->pSelect,pURL_Frame->pCommand,pURL_Frame->pFilename);

        switch (pURL_Frame->Type)
        {
        case GET:
            os_printf("We have a GET request.\n");

            if (os_strcmp(pURL_Frame->pSelect, "client") == 0 &&
                    os_strcmp(pURL_Frame->pCommand, "command") == 0)
            {
                if (os_strcmp(pURL_Frame->pFilename, "info") == 0)
                {
                    json_send(ptrespconn, INFOMATION);
                }
                if (os_strcmp(pURL_Frame->pFilename, "status") == 0)
                {
                    json_send(ptrespconn, CONNECT_STATUS);
                }
                else if (os_strcmp(pURL_Frame->pFilename, "scan") == 0)
                {
                    char *strstr = NULL;
                    strstr = (char *)os_strstr(pusrdata, "&");

                    if (strstr == NULL)
                    {
                        if (pscaninfo == NULL)
                        {
                            pscaninfo = (scaninfo *)os_zalloc(sizeof(scaninfo));
                        }

                        pscaninfo->pespconn = ptrespconn;
                        pscaninfo->pagenum = 0;
                        pscaninfo->page_sn = 0;
                        pscaninfo->data_cnt = 0;
                        wifi_station_scan(NULL, json_scan_cb);
                        } else {
                            strstr ++;

                            if (os_strncmp(strstr, "page", 4) == 0) {
                                if (pscaninfo != NULL) {
                                    pscaninfo->pagenum = *(strstr + 5);
                                    pscaninfo->pagenum -= 0x30;

                                    if (pscaninfo->pagenum > pscaninfo->totalpage || pscaninfo->pagenum == 0) {
                                        response_send(ptrespconn, false);
                                    } else {
                                        json_send(ptrespconn, SCAN);
                                    }
                                } else {
                                    response_send(ptrespconn, false);
                                }
                            } else if(os_strncmp(strstr, "finish", 6) == 0){
                                bss_temp = bss_head;
                                while(bss_temp != NULL) {
                                    bss_head = bss_temp->next.stqe_next;
                                    os_free(bss_temp);
                                    bss_temp = bss_head;
                                }
                                bss_head = NULL;
                                bss_temp = NULL;
                                response_send(ptrespconn, true);
                            } else {
                                response_send(ptrespconn, false);
                            }
                        }
                    } else {
                        response_send(ptrespconn, false);
                    }
                } else if (os_strcmp(pURL_Frame->pSelect, "config") == 0 &&
                           os_strcmp(pURL_Frame->pCommand, "command") == 0) {
                    if (os_strcmp(pURL_Frame->pFilename, "wifi") == 0) {
                        ap_conf = (struct softap_config *)os_zalloc(sizeof(struct softap_config));
                        sta_conf = (struct station_config *)os_zalloc(sizeof(struct station_config));
                        json_send(ptrespconn, WIFI);
                        os_free(sta_conf);
                        os_free(ap_conf);
                        sta_conf = NULL;
                        ap_conf = NULL;
                    }

#if PLUG_DEVICE
                    else if (os_strcmp(pURL_Frame->pFilename, "switch") == 0) {
                        json_send(ptrespconn, SWITCH_STATUS);
                    }
#endif
                    else if (os_strcmp(pURL_Frame->pFilename, "reboot") == 0) {
                        json_send(ptrespconn, REBOOT);
                    } else {
                        response_send(ptrespconn, false);
                    }
                } else if (os_strcmp(pURL_Frame->pSelect, "upgrade") == 0 &&
                        os_strcmp(pURL_Frame->pCommand, "command") == 0) {
                        if (os_strcmp(pURL_Frame->pFilename, "getuser") == 0) {
                            json_send(ptrespconn , USER_BIN);
                        }
                } else {
                    response_send(ptrespconn, false);
                }

                break;

            case POST:
                os_printf("We have a POST request.\n");
                pParseBuffer = (char *)os_strstr(precvbuffer, "\r\n\r\n");

                if (pParseBuffer == NULL) {
                    break;
                }

                pParseBuffer += 4;

                if (os_strcmp(pURL_Frame->pSelect, "config") == 0 &&
                        os_strcmp(pURL_Frame->pCommand, "command") == 0) {

                    if (os_strcmp(pURL_Frame->pFilename, "reboot") == 0) {

                        if (pParseBuffer != NULL) {
                            if (restart_10ms != NULL) {
                                os_timer_disarm(restart_10ms);
                            }

                            if (rstparm == NULL) {
                                rstparm = (rst_parm *)os_zalloc(sizeof(rst_parm));
                            }

                            rstparm->pespconn = ptrespconn;

                            rstparm->parmtype = REBOOT;

                            if (restart_10ms == NULL) {
                                restart_10ms = (os_timer_t *)os_malloc(sizeof(os_timer_t));
                            }

                            os_timer_setfn(restart_10ms, (os_timer_func_t *)restart_10ms_cb, NULL);
                            os_timer_arm(restart_10ms, 10, 0);  // delay 10ms, then do

                            response_send(ptrespconn, true);
                        } else {
                            response_send(ptrespconn, false);
                        }
                    } else if (os_strcmp(pURL_Frame->pFilename, "wifi") == 0) {
                        if (pParseBuffer != NULL) {
                            struct jsontree_context js;
                            user_esp_platform_set_connect_status(DEVICE_CONNECTING);

                            if (restart_10ms != NULL) {
                                os_timer_disarm(restart_10ms);
                            }

                            if (ap_conf == NULL) {
                                ap_conf = (struct softap_config *)os_zalloc(sizeof(struct softap_config));
                            }

                            if (sta_conf == NULL) {
                                sta_conf = (struct station_config *)os_zalloc(sizeof(struct station_config));
                            }

                            jsontree_setup(&js, (struct jsontree_value *)&wifi_req_tree, json_putchar);
                            json_parse(&js, pParseBuffer);

                            if (rstparm == NULL) {
                                rstparm = (rst_parm *)os_zalloc(sizeof(rst_parm));
                            }

                            rstparm->pespconn = ptrespconn;
                            rstparm->parmtype = WIFI;

                            if (sta_conf->ssid[0] != 0x00 || ap_conf->ssid[0] != 0x00) {
                                ap_conf->ssid_hidden = 0;
                                ap_conf->max_connection = 4;

                                if (restart_10ms == NULL) {
                                    restart_10ms = (os_timer_t *)os_malloc(sizeof(os_timer_t));
                                }

                                os_timer_disarm(restart_10ms);
                                os_timer_setfn(restart_10ms, (os_timer_func_t *)restart_10ms_cb, NULL);
                                os_timer_arm(restart_10ms, 10, 0);  // delay 10ms, then do
                            } else {
                                os_free(ap_conf);
                                os_free(sta_conf);
                                os_free(rstparm);
                                sta_conf = NULL;
                                ap_conf = NULL;
                                rstparm =NULL;
                            }

                            response_send(ptrespconn, true);
                        } else {
                            response_send(ptrespconn, false);
                        }
                    }

                    else if (os_strcmp(pURL_Frame->pFilename, "switch") == 0) {
                        if (pParseBuffer != NULL) {
                            struct jsontree_context js;
                            jsontree_setup(&js, (struct jsontree_value *)&StatusTree, json_putchar);
                            json_parse(&js, pParseBuffer);
                            // ----------Altered by Leung 2018.11.12-------START
                            if (user_plug_get_status() == 1)                    // 获取继电器状态
                            {
                                data_send(ptrespconn, true, "{\"status\": 1}"); // 返回APP继电器状态——打开
                            }
                            else
                            {
                                data_send(ptrespconn, true, "{\"status\": 0}"); // 返回APP继电器状态——关闭
                            }
                            // ----------Altered by Leung 2018.11.12-------END
                        } else {
                            response_send(ptrespconn, false);
                        }
                    }
                    else {
                        response_send(ptrespconn, false);
                    }
                }
                else if(os_strcmp(pURL_Frame->pSelect, "upgrade") == 0 &&
                        os_strcmp(pURL_Frame->pCommand, "command") == 0){
                    if (os_strcmp(pURL_Frame->pFilename, "start") == 0){
                        response_send(ptrespconn, true);
                        os_printf("local upgrade start\n");
                        upgrade_lock = 1;
                        system_upgrade_init();
                        system_upgrade_flag_set(UPGRADE_FLAG_START);
                        os_timer_disarm(&upgrade_check_timer);
                        os_timer_setfn(&upgrade_check_timer, (os_timer_func_t *)upgrade_check_func, NULL);
                        os_timer_arm(&upgrade_check_timer, 120000, 0);
                    } else if (os_strcmp(pURL_Frame->pFilename, "reset") == 0) {

                        response_send(ptrespconn, true);
                        os_printf("local upgrade restart\n");
                        system_upgrade_reboot();
                    } else {
                        response_send(ptrespconn, false);
                    }
                }else {
                    response_send(ptrespconn, false);
                }
                 break;
        }

        if (precvbuffer != NULL){
            os_free(precvbuffer);
            precvbuffer = NULL;
        }
        os_free(pURL_Frame);
        pURL_Frame = NULL;
        _temp_exit:
            ;
    }
    else if(upgrade_lock == 1){
        local_upgrade_download(ptrespconn,pusrdata, length);
        if (precvbuffer != NULL){
            os_free(precvbuffer);
            precvbuffer = NULL;
        }
        os_free(pURL_Frame);
        pURL_Frame = NULL;
    }
}

五、解析请求数据包

5.1 check_data()

校验收到数据是否正确,判断收到数据的总长度是否等于“Content-Length:”里所描述的长度。

LOCAL bool ICACHE_FLASH_ATTR
check_data(char *precv, uint16 length)
{
    char length_buf[10] = {0};
    char *ptemp = NULL;
    char *pdata = NULL;
    char *tmp_precvbuffer;
    uint16 tmp_length = length;
    uint32 tmp_totallength = 0;

    ptemp = (char *)os_strstr(precv, "\r\n\r\n");
    
    if (ptemp != NULL) {
        tmp_length -= ptemp - precv;
        tmp_length -= 4;
        tmp_totallength += tmp_length;
        
        pdata = (char *)os_strstr(precv, "Content-Length: ");
        
        if (pdata != NULL){
            pdata += 16;
            tmp_precvbuffer = (char *)os_strstr(pdata, "\r\n");
            
            if (tmp_precvbuffer != NULL){
                os_memcpy(length_buf, pdata, tmp_precvbuffer - pdata);
                dat_sumlength = atoi(length_buf);
                os_printf("A_dat:%u,tot:%u,lenght:%u\n",dat_sumlength,tmp_totallength,tmp_length);
                if(dat_sumlength != tmp_totallength){
                    return false;
                }
            }
        }
    }
    return true;
}

5.2 save_data()

将收到的数据校验长度后,存储起来。

LOCAL char *precvbuffer;
static uint32 dat_sumlength = 0;

LOCAL bool ICACHE_FLASH_ATTR
save_data(char *precv, uint16 length)
{
    bool flag = false;
    char length_buf[10] = {0};
    char *ptemp = NULL;
    char *pdata = NULL;
    uint16 headlength = 0;
    static uint32 totallength = 0;

    ptemp = (char *)os_strstr(precv, "\r\n\r\n");

    if (ptemp != NULL) {
        length -= ptemp - precv;
        length -= 4;
        totallength += length;
        headlength = ptemp - precv + 4;
        pdata = (char *)os_strstr(precv, "Content-Length: ");

        if (pdata != NULL) {
            pdata += 16;
            precvbuffer = (char *)os_strstr(pdata, "\r\n");

            if (precvbuffer != NULL) {
                os_memcpy(length_buf, pdata, precvbuffer - pdata);
                dat_sumlength = atoi(length_buf);
            }
        } else {
            if (totallength != 0x00){
                totallength = 0;
                dat_sumlength = 0;
                return false;
            }
        }
        if ((dat_sumlength + headlength) >= 1024) {
            precvbuffer = (char *)os_zalloc(headlength + 1);
            os_memcpy(precvbuffer, precv, headlength + 1);
        } else {
            precvbuffer = (char *)os_zalloc(dat_sumlength + headlength + 1);
            os_memcpy(precvbuffer, precv, os_strlen(precv));
        }
    } else {
        if (precvbuffer != NULL) {
            totallength += length;
            os_memcpy(precvbuffer + os_strlen(precvbuffer), precv, length);
        } else {
            totallength = 0;
            dat_sumlength = 0;
            return false;
        }
    }

    if (totallength == dat_sumlength) {
        totallength = 0;
        dat_sumlength = 0;
        return true;
    } else {
        return false;
    }
}

5.3 URL_Frame

typedef struct URL_Frame {
    enum ProtocolType Type;
    char pSelect[URLSize];
    char pCommand[URLSize];
    char pFilename[URLSize];
} URL_Frame;

5.4 parse_url()

/******************************************************************************
 * FunctionName : parse_url
 * Description  : parse the received data from the server
 * Parameters   : precv -- the received data
 *                purl_frame -- the result of parsing the url
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
parse_url(char *precv, URL_Frame *purl_frame)
{
    char *str = NULL;
    uint8 length = 0;
    char *pbuffer = NULL;
    char *pbufer = NULL;

    if (purl_frame == NULL || precv == NULL) {
        return;
    }

    pbuffer = (char *)os_strstr(precv, "Host:");

    if (pbuffer != NULL) {
        length = pbuffer - precv;
        pbufer = (char *)os_zalloc(length + 1);
        pbuffer = pbufer;
        os_memcpy(pbuffer, precv, length);
        os_memset(purl_frame->pSelect, 0, URLSize);
        os_memset(purl_frame->pCommand, 0, URLSize);
        os_memset(purl_frame->pFilename, 0, URLSize);

        if (os_strncmp(pbuffer, "GET ", 4) == 0) {
            purl_frame->Type = GET;
            pbuffer += 4;
        } else if (os_strncmp(pbuffer, "POST ", 5) == 0) {
            purl_frame->Type = POST;
            pbuffer += 5;
        }

        pbuffer ++;
        str = (char *)os_strstr(pbuffer, "?");

        if (str != NULL) {
            length = str - pbuffer;
            os_memcpy(purl_frame->pSelect, pbuffer, length);
            str ++;
            pbuffer = (char *)os_strstr(str, "=");

            if (pbuffer != NULL) {
                length = pbuffer - str;
                os_memcpy(purl_frame->pCommand, str, length);
                pbuffer ++;
                str = (char *)os_strstr(pbuffer, "&");

                if (str != NULL) {
                    length = str - pbuffer;
                    os_memcpy(purl_frame->pFilename, pbuffer, length);
                } else {
                    str = (char *)os_strstr(pbuffer, " HTTP");

                    if (str != NULL) {
                        length = str - pbuffer;
                        os_memcpy(purl_frame->pFilename, pbuffer, length);
                    }
                }
            }
        }

        os_free(pbufer);
    } else {
        return;
    }
}

六、回发响应数据包

6.1 response_send()

回复简单格式,里面调用data_send()

/******************************************************************************
 * FunctionName : response_send
 * Description  : processing the send result
 * Parameters   : arg -- argument to set for client or server
 *                responseOK --  true or false
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
response_send(void *arg, bool responseOK)
{
    struct espconn *ptrespconn = arg;

    data_send(ptrespconn, responseOK, NULL);
}

6.2 json_send()

里面生成JSON数据json_ws_send()参考ESP8266学习笔记(7)——JSON接口使用

/******************************************************************************
 * FunctionName : json_send
 * Description  : processing the data as json format and send to the client or server
 * Parameters   : arg -- argument to set for client or server
 *                ParmType -- json format type
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
json_send(void *arg, ParmType ParmType)
{
    char *pbuf = NULL;
    pbuf = (char *)os_zalloc(jsonSize);
    struct espconn *ptrespconn = arg;

    switch (ParmType) {

#if PLUG_DEVICE
        case SWITCH_STATUS:
            json_ws_send((struct jsontree_value *)&StatusTree, "switch", pbuf);
            os_printf("switch:%s", pbuf);
            break;
#endif

        case INFOMATION:
            json_ws_send((struct jsontree_value *)&INFOTree, "info", pbuf);
            break;

        case WIFI:
            json_ws_send((struct jsontree_value *)&wifi_info_tree, "wifi", pbuf);
            break;

        case CONNECT_STATUS:
            json_ws_send((struct jsontree_value *)&con_status_tree, "info", pbuf);
            break;

        case USER_BIN:
            json_ws_send((struct jsontree_value *)&userinfo_tree, "user_info", pbuf);
            break;
        case SCAN: {
            u8 i = 0;
            u8 scancount = 0;
            struct bss_info *bss = NULL;
            bss = bss_head;
            if (bss == NULL) {
                os_free(pscaninfo);
                pscaninfo = NULL;
                os_sprintf(pbuf, "{\n\"successful\": false,\n\"data\": null\n}");
            } else {
                do {
                    if (pscaninfo->page_sn == pscaninfo->pagenum) {
                        pscaninfo->page_sn = 0;
                        os_sprintf(pbuf, "{\n\"successful\": false,\n\"meessage\": \"repeated page\"\n}");
                        break;
                    }

                    scancount = scannum - (pscaninfo->pagenum - 1) * 8;

                    if (scancount >= 8) {
                        pscaninfo->data_cnt += 8;
                        pscaninfo->page_sn = pscaninfo->pagenum;

                        if (pscaninfo->data_cnt > scannum) {
                            pscaninfo->data_cnt -= 8;
                            os_sprintf(pbuf, "{\n\"successful\": false,\n\"meessage\": \"error page\"\n}");
                            break;
                        }

                        json_ws_send((struct jsontree_value *)&scan_tree, "scan", pbuf);
                    } else {
                        pscaninfo->data_cnt += scancount;
                        pscaninfo->page_sn = pscaninfo->pagenum;

                        if (pscaninfo->data_cnt > scannum) {
                            pscaninfo->data_cnt -= scancount;
                            os_sprintf(pbuf, "{\n\"successful\": false,\n\"meessage\": \"error page\"\n}");
                            break;
                        }

                        char *ptrscanbuf = (char *)os_zalloc(jsonSize);
                        char *pscanbuf = ptrscanbuf;
                        os_sprintf(pscanbuf, ",\n\"ScanResult\": [\n");
                        pscanbuf += os_strlen(pscanbuf);

                        for (i = 0; i < scancount; i ++) {
                            JSONTREE_OBJECT(page_tree,
                                            JSONTREE_PAIR("page", &scaninfo_tree));
                            json_ws_send((struct jsontree_value *)&page_tree, "page", pscanbuf);
                            os_sprintf(pscanbuf + os_strlen(pscanbuf), ",\n");
                            pscanbuf += os_strlen(pscanbuf);
                        }

                        os_sprintf(pscanbuf - 2, "]\n");
                        JSONTREE_OBJECT(scantree,
                                        JSONTREE_PAIR("TotalPage", &scan_callback),
                                        JSONTREE_PAIR("PageNum", &scan_callback));
                        JSONTREE_OBJECT(scanres_tree,
                                        JSONTREE_PAIR("Response", &scantree));
                        JSONTREE_OBJECT(scan_tree,
                                        JSONTREE_PAIR("scan", &scanres_tree));
                        json_ws_send((struct jsontree_value *)&scan_tree, "scan", pbuf);
                        os_memcpy(pbuf + os_strlen(pbuf) - 4, ptrscanbuf, os_strlen(ptrscanbuf));
                        os_sprintf(pbuf + os_strlen(pbuf), "}\n}");
                        os_free(ptrscanbuf);
                    }
                } while (0);
            }

            break;
        }

        default :
            break;
    }

    data_send(ptrespconn, true, pbuf);
    os_free(pbuf);
    pbuf = NULL;
}

6.3 data_send()

/******************************************************************************
 * FunctionName : data_send
 * Description  : processing the data as http format and send to the client or server
 * Parameters   : arg -- argument to set for client or server
 *                responseOK -- true or false
 *                psend -- The send data
 * Returns      :
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
data_send(void *arg, bool responseOK, char *psend)
{
    uint16 length = 0;
    char *pbuf = NULL;
    char httphead[256];
    struct espconn *ptrespconn = arg;
    os_memset(httphead, 0, 256);

    if (responseOK) {
        os_sprintf(httphead,
                   "HTTP/1.0 200 OK\r\nContent-Length: %d\r\nServer: lwIP/1.4.0\r\n",
                   psend ? os_strlen(psend) : 0);

        if (psend) {
            os_sprintf(httphead + os_strlen(httphead),
                       "Content-type: application/json\r\nExpires: Fri, 10 Apr 2008 14:00:00 GMT\r\nPragma: no-cache\r\n\r\n");
            length = os_strlen(httphead) + os_strlen(psend);
            pbuf = (char *)os_zalloc(length + 1);
            os_memcpy(pbuf, httphead, os_strlen(httphead));
            os_memcpy(pbuf + os_strlen(httphead), psend, os_strlen(psend));
        } else {
            os_sprintf(httphead + os_strlen(httphead), "\n");
            length = os_strlen(httphead);
        }
    } else {
        os_sprintf(httphead, "HTTP/1.0 400 BadRequest\r\n\
Content-Length: 0\r\nServer: lwIP/1.4.0\r\n\n");
        length = os_strlen(httphead);
    }

    if (psend) {
        espconn_sent(ptrespconn, pbuf, length);
    } 
    else {
        espconn_sent(ptrespconn, httphead, length);
    }

    if (pbuf) {
        os_free(pbuf);
        pbuf = NULL;
    }
}

七、printf打印内容

len:491
A_dat:25,tot:25,lenght:25
pusrdata:POST /config?command=switch HTTP/1.1
Accept: application/json,application/xml,application/xhtml+xml,text/html;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh
Connection: keep-alive
Content-Type: application/json; charset=utf-8
User-Agent: Mozilla/5.0 (Linux; U; Android 5.0.2; zh-cn; Redmi Note 2 Build/LRX22G) AppleWebKit/533.1 (KHTML, like Gecko) Version/5.0 Mobile Safari/533.1
Content-Length: 25
Host: 192.168.0.52

{"Response":{"status":0}}
Type:1, Select:config, Command:command, Filename:switch We have a POST request.

• 由 Leung 写于 2019 年 2 月 27 日

• 参考:ESP8266_NONOS_SDK-2.1.0[vqhl]
    ESP8266 Non-OS SDK API参考[zj6w]

扫描二维码关注公众号,回复: 5454696 查看本文章

猜你喜欢

转载自blog.csdn.net/weixin_34247032/article/details/88295352
今日推荐