web server (2) ------post数据接收

上一篇讲到简单的web server,控灯是靠网页的动作action来进行操作的,主要是应用的HTTP的get 请求方法,如果你需要传输数据get请求方法似乎就不够用了,所以换成post请求传输数据。传输少量数据并没有什么问题,但要是大量数据需要对LWIP的函数进行深挖才能进行大量数据的全部解析,本人在解析了几K数据之后wireshark,再大的数据仍然接收不了,且解析数据包复杂繁琐,所以放弃这个方法。

const unsigned char htmldata[] = "HTTP/1.1 200 OK\r\nContent-type:text/html\r\n\r\n\
        <html>	\
        <head><title> A LwIP WebServer !!</title></head> \
	    <center>A WebServer Based on LwIP v1.4.1!</center>\
	    </html>";
            
const static char http_html_hdr_len_with_body[] = "HTTP/1.1 200 OK\r\nContent-type:text/html\r\n\
Content-Length: %d\r\n\
\r\n%s";
const static char http_ota[] = "\
<html>\r\n\
<head>\r\n\
    <title>UploadFiles</title>\r\n\
</head>\r\n\
<body>\r\n\
<form action=\"ota\" method=\"post\" enctype=\"multipart/form-data\">\r\n\
    <p><input type=\"file\" name=\"upload\"></p>\r\n\
    <p><input type=\"submit\" value=\"submit\"></p>\r\n\
</form>\r\n\
</body>\r\n\
</html>";            
            
static  u8 key_push_down = false;

static void key_down_isr(void *context)     //gpio中断
{
    key_push_down = true;
    
} 
void httpserver_send_html(struct tcp_pcb *pcb)
{
    err_t err;
    char * p_out = NULL;
    
//    p_out = wl_zmalloc( 1500 );
//    if( p_out == NULL ) {
//        
//        printf("malloc failed");
//    }    
    
    //sprintf( p_out, http_html_hdr_len_with_body, strlen(http_ota), http_ota );
    err = tcp_write(pcb, http_ota, sizeof(http_ota), 1);
    if(err != ERR_OK) {
        printf("write err!\n");
    }
    err = tcp_output(pcb);
    if(err != ERR_OK) {
        printf("output err!\n");
    }     
    printf("%s,%d\n",__func__,__LINE__);

}



static bool end_signal = FALSE;


static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{   
    struct pbuf *q;
    q = p;
    
    static int count = 0;
    char * buf_user = NULL;
    buf_user = wl_zmalloc(2048);
    if( buf_user == NULL )
    {
        printf("malloc failed");
    }
    uint16_t cnt = 0;
    char *temp_data = NULL;
    char *data = NULL;
    printf("%s,%d\n",__func__,__LINE__);
    /* We perform here any necessary processing on the pbuf */
    if (p != NULL) {        
        /* We call this function to tell the LwIp that we have processed the data */
        /* This lets the stack advertise a larger window, so more data can be received*/
        tcp_recved(pcb, p->tot_len);
        end_signal = TRUE;
        printf("%s,%d, tot_len = %d\n",__func__,__LINE__,  p->tot_len);
        data =  p->payload;
        temp_data = p->payload;

        if(p->len >=5 && (strncmp(data, "GET /", 5) == 0)) {
            httpserver_send_html(pcb);     
         
            printf("%s,%d\n",__func__,__LINE__);
        } else if (p->len >= 8 && (strncmp(data, "POST /ota", strlen( "POST /ota" )) == 0)) {
            httpserver_send_html(pcb);

            
            memcpy( buf_user+cnt, temp_data, strlen(temp_data));
            cnt += strlen(temp_data);
            printf("data length : %d\n", strlen(temp_data));
            temp_data = p->next->payload;
            q = q->next;          /
            memcpy( buf_user+cnt, temp_data, strlen(temp_data));
            printf("data length 2 : %d\n", strlen(temp_data));
//            cnt += strlen(temp_data);
//            temp_data = q->payload;
//            memcpy( buf_user+cnt, temp_data, strlen(temp_data));

            
            printf("upload\n");
            printf("-------------   POST INFORMATION    -------------\n");
            printf("-------------\n%s\n-------------\n", buf_user);
            if( buf_user != NULL ) {
                wl_free( buf_user );
                buf_user = NULL;        
            } 
            //count++;
            
        } else {
            printf("-------------   FILE RECEIVE   -------------\n");
            
            do {
                memcpy( buf_user+cnt, temp_data, strlen(temp_data));
                printf("data length : %d\n", strlen(temp_data));
                cnt += strlen(temp_data);
                temp_data = q->next->payload;
                q = q->next;
            } while (q != NULL);   
//            memcpy( buf_user+cnt, temp_data, strlen(temp_data));
//            printf("data length 1: %d\n", strlen(temp_data));
//            cnt += strlen(temp_data);
//            temp_data = p->next->payload;
//            memcpy( buf_user+cnt, temp_data, strlen(temp_data));
//            printf("data length 2: %d\n", strlen(temp_data));
//            q = q->next;
//            cnt += strlen(temp_data);
//            temp_data = q->payload;
//            memcpy( buf_user+cnt, temp_data, strlen(temp_data));
//            printf("data length 3: %d\n", strlen(temp_data));
            
            
            printf("-------------   data    -------------\n");
            printf("-------------\n%s\n-------------\n", buf_user);
            if( buf_user != NULL ) {
                wl_free( buf_user );
                buf_user = NULL;        
            } 

        }
        //pbuf_free(p);
        //tcp_close(pcb);
    } else if (err == ERR_OK) {
        /* When the pbuf is NULL and the err is ERR_OK, the remote end is closing the connection. */
        /* We free the allocated memory and we close the connection */
        pbuf_free(p);
        printf("---------------     receive over    -------------------\n");
        
        return tcp_close(pcb);
    }

    return ERR_OK;
}




static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{     
    tcp_recv(pcb, http_recv);
    return ERR_OK;
}



static void web_server_init(void)
{
    struct tcp_pcb *pcb = NULL;
    
    pcb = tcp_new();

    tcp_bind(pcb, IP_ADDR_ANY, 80); 

    pcb = tcp_listen(pcb);

    tcp_accept(pcb, http_accept);
}

void server_task(void *context)
{

    gpio_init();
    
    while(!key_push_down){
        wl_os_mdelay(1000);
    }
    printf("web server start \n");
    web_server_init();
}


void server_entry(void)
{
	wl_create_thread("webserver thread", 512, MAIN_TASK_PRIO, (thread_func_t)server_task, NULL);
}

注意:1.最好学习一下http,html相关,网页数组,可以用字符串,也可以用网页文件转成的十六进制数组,转换工具可以网上自行搜索

2.大数据接收时,表面上tcp_recved(pcb, p->tot_len)只接受了一部分数据,上一篇netbuf_data(inbuf, (void**)&buf, &buflen)也是一样,一个大数据包过来,会进行分包,分包接收之后,要想解析完整数据需要进行指针移动p,netbuf_data要和netbuf_next配合使用才能完全解析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值