上传个LwIP HttpClient源码(raw api)

2020-02-11 09:12发布

上传个LwIP HttpClient源码(raw api),有K60板子移植LWip的可以试试

webclient.rar (3.69 KB, 下载次数: 135) 2014-12-31 11:48 上传 点击文件名下载附件
webclient
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
51条回答
superrf
1楼-- · 2020-02-11 12:50
本帖最后由 superrf 于 2014-12-31 11:59 编辑
  1. /*
  2.         HTTP CLIENT FOR RAW LWIP
  3.         (c) 2008-2009 Noyens Kenneth
  4.         PUBLIC VERSION V0.2 16/05/2009

  5.         This program is free software; you can redistribute it and/or modify
  6.         it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1 as published by
  7.         the Free Software Foundation.

  8.         This program is distributed in the hope that it will be useful,
  9.         but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.         GNU Lesser General Public License for more details.

  12.         You should have received a copy of the GNU General Public License
  13.         along with this program; if not, write to the
  14.         Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

  15. */
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include "webclient.h"

  19. #include "utils/ustdlib.h"

  20. // Close a PCB(connection)
  21. void hc_clearpcb(struct tcp_pcb *pcb)
  22. {
  23.         if(pcb != NULL)
  24.         {
  25.                 // Close the TCP connection
  26.                     tcp_close(pcb);
  27.         }
  28. }

  29. // Function that lwip calls for handling recv'd data
  30. err_t hc_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
  31. {
  32.         struct hc_state *state = arg;
  33.         char * page = NULL;
  34.         struct pbuf * temp_p;
  35.         hc_errormsg errormsg = GEN_ERROR;
  36.         int i;

  37.     if((err == ERR_OK) && (p != NULL))
  38.     {
  39.                 tcp_recved(pcb, p->tot_len);

  40.                 // Add payload (p) to state
  41.                 temp_p = p;
  42.                 while(temp_p != NULL)
  43.                 {
  44.                         state->RecvData = realloc(state->RecvData, temp_p->len + state->Len + 1);

  45.                         // CHECK 'OUT OF MEM'
  46.                         if(state->RecvData == NULL)
  47.                         {
  48.                                 // OUT OF MEMORY
  49.                                 (*state->ReturnPage)(state->Num, OUT_MEM, NULL, 0);       
  50.                                 return(ERR_OK);
  51.                         }

  52.                         strncpy(state->RecvData + state->Len, temp_p->payload, temp_p->len);
  53.                         state->RecvData[temp_p->len + state->Len] = '';                       
  54.                         state->Len += temp_p->len;

  55.                         temp_p = temp_p->next;
  56.                 }

  57.                 // Removing payloads

  58.                 while(p != NULL)
  59.                 {
  60.                         temp_p = p->next;
  61.                         pbuf_free(p);
  62.                         p = temp_p;
  63.                 }

  64.     }

  65.     // NULL packet == CONNECTION IS CLOSED(by remote host)
  66.     else if((err == ERR_OK) && (p == NULL))
  67.     {       
  68.                 // Simple code for checking 200 OK
  69.                 for(i=0; i < state->Len; i++)
  70.                 {
  71.                         if(errormsg == GEN_ERROR)
  72.                         {
  73.                                 // Check for 200 OK
  74.                                 if((*(state->RecvData+i) == '2') && (*(state->RecvData+ ++i) == '0') && (*(state->RecvData+ ++i) == '0')) errormsg = OK;
  75.                                 if(*(state->RecvData+i) == ' ') errormsg = NOT_FOUND;
  76.                         }
  77.                         else
  78.                         {
  79.                                 // Remove headers
  80.                                 if((*(state->RecvData+i) == ' ') && (*(state->RecvData+ ++i) == ' ') && (*(state->RecvData+ ++i) == ' ') && (*(state->RecvData + ++i) == ' '))
  81.                                 {
  82.                                         i++;
  83.                                         page = malloc(strlen(state->RecvData+i));
  84.                                         strcpy(page, state->RecvData+i);
  85.                                         break;
  86.                                 }
  87.                         }
  88.                 }

  89.                 if(errormsg == OK)
  90.                 {
  91.                         // Put recv data to ---> p->ReturnPage
  92.                         (*state->ReturnPage)(state->Num, OK, page, state->Len);
  93.                 }
  94.                 else
  95.                 {
  96.                         // 200 OK not found Return NOT_FOUND (WARNING: NOT_FOUND COULD ALSO BE 5xx SERVER ERROR, ...)
  97.                         (*state->ReturnPage)(state->Num, errormsg, NULL, 0);
  98.                 }

  99.         // Clear the PCB
  100.         hc_clearpcb(pcb);

  101.                 // free the memory containing state
  102.                 free(state->RecvData);
  103.                 free(state);
  104.     }

  105.     return(ERR_OK);
  106. }

  107. // Function that lwip calls when there is an error
  108. static void hc_error(void *arg, err_t err)
  109. {
  110.     struct hc_state *state = arg;
  111.     // pcb already deallocated

  112.     // Call return function
  113.     // TO-DO: Check err_t err for out_mem, ...
  114.     (*state->ReturnPage)(state->Num, GEN_ERROR, NULL, 0);

  115.     free(state->RecvData);
  116.     free(state->PostVars);
  117.     free(state->Page);
  118.     free(state);
  119. }

  120. // Function that lwip calls when the connection is idle
  121. // Here we can kill connections that have stayed idle for too long
  122. static err_t hc_poll(void *arg, struct tcp_pcb *pcb)
  123. {
  124.     struct hc_state *state = arg;

  125.     state->ConnectionTimeout++;
  126.     if(state->ConnectionTimeout > 20)
  127.     {
  128.         // Close the connection
  129.         tcp_abort(pcb);

  130.                 // Give err msg to callback function
  131.                 // Call return function
  132.                 (*state->ReturnPage)(state->Num, TIMEOUT, NULL, 0);
  133.     }

  134.     return(ERR_OK);
  135. }

  136. // lwip calls this function when the remote host has successfully received data (ack)
  137. static err_t hc_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
  138. {
  139.     struct hc_state *state = arg;

  140.     // Reset connection timeout
  141.     state->ConnectionTimeout = 0;

  142.     return(ERR_OK);
  143. }

  144. // lwip calls this function when the connection is established
  145. static err_t hc_connected(void *arg, struct tcp_pcb *pcb, err_t err)
  146. {
  147.     struct hc_state *state = arg;
  148.     char  * headers;

  149.     // error?
  150.     if(err != ERR_OK)
  151.     {
  152.         hc_clearpcb(pcb);

  153.         // Call return function
  154.         (*state->ReturnPage)(state->Num, GEN_ERROR, NULL, 0);

  155.         // Free wc state
  156.         free(state->RecvData);
  157.         free(state);

  158.         return(ERR_OK);
  159.     }

  160.     // Define Headers
  161.     if(state->PostVars == NULL)
  162.     {       
  163.         // GET headers (without page)(+ ) = 19
  164.         headers = malloc(19 + strlen(state->Page));
  165.         usprintf(headers,"GET /%s HTTP/1.0 ", state->Page);
  166.     }
  167.     else
  168.     {
  169.         // POST headers (without PostVars or Page)(+ ) = 91
  170.         // Content-length: %d <==                                                    ??? (max 10)
  171.         headers = malloc(91 + strlen(state->PostVars) + strlen(state->Page) + 10);
  172.         usprintf(headers, "POST /%s HTTP/1.0 Content-type: application/x-www-form-urlencoded Content-length: %d %s ", state->Page, strlen(state->PostVars), state->PostVars);
  173.     }

  174.     // Check if we are nut running out of memory
  175.     if(headers == NULL)
  176.     {
  177.         hc_clearpcb(pcb);

  178.         // Call return function
  179.         (*state->ReturnPage)(state->Num, OUT_MEM, NULL, 0);

  180.         // Free wc state
  181.         free(state->RecvData);
  182.         free(state);

  183.         return(ERR_OK);
  184.     }

  185.     // Setup the TCP receive function
  186.     tcp_recv(pcb, hc_recv);

  187.     // Setup the TCP error function
  188.     tcp_err(pcb, hc_error);

  189.     // Setup the TCP polling function/interval         //TCP_POLL IS NOT CORRECT DEFINED @ DOC!!!
  190.     tcp_poll(pcb, hc_poll, 10);                                                

  191.     // Setup the TCP sent callback function
  192.     tcp_sent(pcb, hc_sent);

  193.     // Send data
  194.     tcp_write(pcb, headers, strlen(headers), 1);
  195.     tcp_output(pcb);

  196.     // remove headers
  197.     free(headers);
  198.     free(state->PostVars);                        // postvars are send, so we don't need them anymore
  199.     free(state->Page);                                    // page is requested, so we don't need it anymore

  200.     return(ERR_OK);
  201. }


  202. // Public function for request a webpage (REMOTEIP, ...
  203. int hc_open(struct ip_addr remoteIP, char *Page, char *PostVars, void (* returnpage)(u8_t, hc_errormsg, char *, u16_t))
  204. {
  205.         struct tcp_pcb *pcb = NULL;
  206.         struct hc_state *state;
  207.         static u8_t num = 0;
  208.         // local port
  209.         u16_t port= 4545;        

  210.         // Get a place for a new webclient state in the memory
  211.         state = malloc(sizeof(struct hc_state));

  212.         // Create a new PCB (PROTOCOL CONTROL BLOCK)
  213.         pcb = tcp_new();
  214.         if(pcb == NULL || state == NULL)
  215.         {
  216.                 //UARTprintf("hc_open: Not enough memory for pcb or state ");       
  217.                 //Not enough memory
  218.                 return 0;
  219.         }

  220.         // Define webclient state vars
  221.         num++;
  222.         state->Num = num;
  223.         state->RecvData = NULL;
  224.         state->ConnectionTimeout = 0;
  225.         state->Len = 0;
  226.         state->ReturnPage = returnpage;

  227.         // Make place for PostVars & Page
  228.         if(PostVars != NULL) state->PostVars = malloc(strlen(PostVars) +1);
  229.         state->Page = malloc(strlen(Page) +1);

  230.         // Check for "out of memory"
  231.         if(state->Page == NULL || (state->PostVars == NULL && PostVars != NULL))
  232.         {
  233.                 free(state->Page);
  234.                 free(state->PostVars);
  235.                 free(state);
  236.                 tcp_close(pcb);
  237.                 return 0;
  238.         }
  239.         // Place allocated copy data
  240.         strcpy(state->Page, Page);
  241.         if(PostVars != NULL) strcpy(state->PostVars, PostVars);

  242.         // Bind to local IP & local port
  243.         while(tcp_bind(pcb, IP_ADDR_ANY, port) != ERR_OK)
  244.         {
  245.                 // Local port in use, use port+1
  246.                 port++;
  247.         }

  248.         // Use conn -> argument(s)
  249.         tcp_arg(pcb, state);

  250.         // Open connect (SEND SYN)
  251.         tcp_connect(pcb, &remoteIP, 80, hc_connected);

  252.         return num;
  253. }
复制代码
nongxiaoming
2楼-- · 2020-02-11 14:17
这代码惨不忍睹啊
activeleo
3楼-- · 2020-02-11 16:00
好东西,最近有时间研究下远程控制的WEB方式!
Juggernaut
4楼-- · 2020-02-11 16:01
 精彩回答 2  元偷偷看……
superrf
5楼-- · 2020-02-11 19:40
使用范例
hc_open(*ipaddr, "/", NULL, page_recv);       

void page_recv(u8_t num, hc_errormsg errormsg, char * page, u16_t len)
{
        if(page) UARTprintf("%s ", page);
        else
        {       
                UARTprintf("error: ");
                if(errormsg == OUT_MEM) UARTprintf("OUT MEM");
                else if(errormsg == TIMEOUT) UARTprintf("TIME OUT");
                else if(errormsg == NOT_FOUND) UARTprintf("NO 200 OK");
                else if(errormsg == GEN_ERROR) UARTprintf("GEN ERROR");
                else UARTprintf("?? ERROR");
                UARTprintf(" ");
        }
}
fengyunyu
6楼-- · 2020-02-11 20:53
nongxiaoming 发表于 2014-12-31 11:52
这代码惨不忍睹啊

怎么个惨不忍睹法?这个代码貌似是FSL配套例程。

一周热门 更多>