搜索
bottom↓
回复: 51

上传个LwIP HttpClient源码(raw api)

[复制链接]

出0入0汤圆

发表于 2014-12-31 11:49:51 | 显示全部楼层 |阅读模式
上传个LwIP HttpClient源码(raw api),有K60板子移植LWip的可以试试

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2014-12-31 11:50:46 | 显示全部楼层
本帖最后由 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] = '\0';                       
  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) == '\n') errormsg = NOT_FOUND;
  76.                         }
  77.                         else
  78.                         {
  79.                                 // Remove headers
  80.                                 if((*(state->RecvData+i) == '\r') && (*(state->RecvData+ ++i) == '\n') && (*(state->RecvData+ ++i) == '\r') && (*(state->RecvData + ++i) == '\n'))
  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)(+ \0) = 19
  164.         headers = malloc(19 + strlen(state->Page));
  165.         usprintf(headers,"GET /%s HTTP/1.0\r\n\r\n", state->Page);
  166.     }
  167.     else
  168.     {
  169.         // POST headers (without PostVars or Page)(+ \0) = 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\r\nContent-type: application/x-www-form-urlencoded\r\nContent-length: %d\r\n\r\n%s\r\n\r\n", 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\n");       
  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. }
复制代码

出0入0汤圆

发表于 2014-12-31 11:52:30 | 显示全部楼层
这代码惨不忍睹啊

出0入0汤圆

发表于 2014-12-31 11:53:29 | 显示全部楼层
好东西,最近有时间研究下远程控制的WEB方式!

出0入0汤圆

发表于 2014-12-31 11:58:49 | 显示全部楼层
头晕,这代码

出0入0汤圆

 楼主| 发表于 2014-12-31 12:18:31 | 显示全部楼层
使用范例
hc_open(*ipaddr, "/", NULL, page_recv);       

void page_recv(u8_t num, hc_errormsg errormsg, char * page, u16_t len)
{
        if(page) UARTprintf("%s\n\n\n", 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("\n");
        }
}

出100入101汤圆

发表于 2014-12-31 12:47:42 | 显示全部楼层

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

出0入0汤圆

发表于 2014-12-31 13:17:23 | 显示全部楼层
fengyunyu 发表于 2014-12-31 12:47
怎么个惨不忍睹法?这个代码貌似是FSL配套例程。

我看的时候你没有排版,代码都没高亮,所以……

出0入0汤圆

发表于 2015-1-7 20:13:43 | 显示全部楼层
学习tcpip中,感谢分享

出0入0汤圆

发表于 2015-1-8 09:12:08 | 显示全部楼层
手头上用的是STM32板子,不知道能否移植

出0入0汤圆

 楼主| 发表于 2015-1-8 09:29:55 | 显示全部楼层
chwe1112 发表于 2015-1-8 09:12
手头上用的是STM32板子,不知道能否移植

可以移植,只要剩余内存够就行

出0入0汤圆

发表于 2015-1-9 17:06:15 | 显示全部楼层
有没有应用例程

出0入0汤圆

 楼主| 发表于 2015-1-9 17:08:00 | 显示全部楼层
sober 发表于 2015-1-9 17:06
有没有应用例程

6楼就是使用范例

出0入0汤圆

发表于 2015-1-9 21:36:15 | 显示全部楼层
不错 ,lwip的移植,必须要有个带网络的板子才能跑起来 。

出0入0汤圆

 楼主| 发表于 2015-1-9 21:41:09 | 显示全部楼层
K60带网络功能,你的飞币快够了

出0入0汤圆

发表于 2015-1-9 21:56:31 | 显示全部楼层
superrf 发表于 2015-1-9 21:41
K60带网络功能,你的飞币快够了

是哦 ,等飞币够了换一块 。也把lwip移植进去

出0入0汤圆

发表于 2015-1-12 16:00:02 | 显示全部楼层
你好,有没有例程工程,许多库没有,是基于LWIP开发吗

出0入0汤圆

 楼主| 发表于 2015-1-12 16:03:01 | 显示全部楼层
sober 发表于 2015-1-12 16:00
你好,有没有例程工程,许多库没有,是基于LWIP开发吗

只要移植了LWIP就可用,目前还没有K60的工程呢。

出0入0汤圆

发表于 2015-1-12 16:26:13 | 显示全部楼层
#include "utils/lwiplib.h"

#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "ethernet.h"

在lwip中没有


出0入0汤圆

 楼主| 发表于 2015-1-12 16:35:00 | 显示全部楼层
sober 发表于 2015-1-12 16:26
#include "utils/lwiplib.h"

#include "inc/hw_memmap.h"

没有可用删掉,移植多少需要改动一部分代码

出0入0汤圆

发表于 2015-1-12 17:37:38 | 显示全部楼层
superrf 发表于 2015-1-12 16:35
没有可用删掉,移植多少需要改动一部分代码

谢谢楼主,我已移植成功,头文件需加
#include "lwip/pbuf.h"
#include "lwip/tcp.h"

出0入0汤圆

 楼主| 发表于 2015-1-12 17:55:57 | 显示全部楼层
sober 发表于 2015-1-12 17:37
谢谢楼主,我已移植成功,头文件需加
#include "lwip/pbuf.h"
#include "lwip/tcp.h"

移植到哪个平台,K60还是STM32?

出0入0汤圆

发表于 2015-1-12 18:00:36 | 显示全部楼层
superrf 发表于 2015-1-12 17:55
移植到哪个平台,K60还是STM32?

GD32F107,STM32F107,GD和ST通用

出0入0汤圆

 楼主| 发表于 2015-1-12 18:03:08 | 显示全部楼层
sober 发表于 2015-1-12 18:00
GD32F107,STM32F107,GD和ST通用

GD32F107什么价格?跟STM32F107兼容吗?

出0入0汤圆

发表于 2015-1-12 18:11:33 | 显示全部楼层
superrf 发表于 2015-1-8 09:29
可以移植,只要剩余内存够就行

请教下Stm32f103ZET6可以么? 否则 是否可以加扩展存储器?

出0入0汤圆

 楼主| 发表于 2015-1-12 18:18:21 | 显示全部楼层
扬帆远航 发表于 2015-1-12 18:11
请教下Stm32f103ZET6可以么? 否则 是否可以加扩展存储器?

当然可以了,不需要扩展存储器

出0入0汤圆

发表于 2015-1-12 18:21:46 | 显示全部楼层
superrf 发表于 2015-1-12 18:18
当然可以了,不需要扩展存储器

谢谢,今天刚买的板子..

出0入0汤圆

发表于 2015-1-12 18:38:36 | 显示全部楼层
superrf 发表于 2015-1-12 18:03
GD32F107什么价格?跟STM32F107兼容吗?

GD32F107兼容STM32F107,GD比ST便宜,我们用样片进行开发,具体价格不太清楚

出0入0汤圆

发表于 2015-1-12 18:44:26 | 显示全部楼层
谢谢,回头试试

出0入0汤圆

发表于 2015-1-12 18:45:53 | 显示全部楼层
谢谢楼主,一直不知道raw lwip和带任务的有什么区别

出0入0汤圆

发表于 2015-1-12 18:51:49 | 显示全部楼层
本帖最后由 sober 于 2015-1-12 18:53 编辑

我的网络数据缓冲为512KB,LWIP我裁剪到10K,网络应用有TcpServer、UdpServer、HttpClient

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2015-1-12 18:55:50 | 显示全部楼层
楼主有做lwip的DNS吗

出0入0汤圆

发表于 2015-1-12 19:46:23 | 显示全部楼层
不错,待我下下来研究下

出0入0汤圆

发表于 2015-1-12 19:59:17 | 显示全部楼层
不错 ,LWIP协议栈 ,网络通信的好工具 !

出0入0汤圆

发表于 2015-1-12 20:00:51 | 显示全部楼层
benhaha 发表于 2015-1-12 18:45
谢谢楼主,一直不知道raw lwip和带任务的有什么区别

raw lwip 是裸的 。
带任务的就是带操作系统 ,常见ucos 2

出0入0汤圆

发表于 2015-1-12 20:02:21 | 显示全部楼层
扬帆远航 发表于 2015-1-12 18:11
请教下Stm32f103ZET6可以么? 否则 是否可以加扩展存储器?

Stm32f103ZET6 可以的,这个芯片不带MAC ,需要外接mac 和PHY !

出0入0汤圆

 楼主| 发表于 2015-1-12 21:14:31 | 显示全部楼层
qs6361036 发表于 2015-1-12 20:02
Stm32f103ZET6 可以的,这个芯片不带MAC ,需要外接mac 和PHY !

Stm32f103ZET6 通常外接ENC28J60

出0入0汤圆

 楼主| 发表于 2015-1-12 21:15:53 | 显示全部楼层
sober 发表于 2015-1-12 18:55
楼主有做lwip的DNS吗

lwip带DNS

出0入0汤圆

 楼主| 发表于 2015-1-12 21:19:49 | 显示全部楼层
dns_gethostbyname("www.baidu.com", &resolved, dns_serverfound, NULL);
void dns_serverfound(const char *name, struct ip_addr *ipaddr, void *arg)
{
        if ((ipaddr) && (ipaddr->addr))
        {
                // ipaddr->addr;
        }
}

出0入0汤圆

发表于 2015-1-12 21:21:28 | 显示全部楼层
呵呵 k60有mqx有rtcs有webserver的,很容易就实现网页啦。

出0入0汤圆

 楼主| 发表于 2015-1-12 21:26:13 | 显示全部楼层
sblpp 发表于 2015-1-12 21:21
呵呵 k60有mqx有rtcs有webserver的,很容易就实现网页啦。

RTCS需要单独购买,lwip是开源的

出0入0汤圆

发表于 2015-1-12 21:32:53 | 显示全部楼层
superrf 发表于 2015-1-12 21:14
Stm32f103ZET6 通常外接ENC28J60

是的  ,外接ENC28J60 比较常见 !

出0入0汤圆

发表于 2015-1-12 21:55:48 | 显示全部楼层
superrf 发表于 2015-1-12 21:26
RTCS需要单独购买,lwip是开源的

谁说的?
rtcs集成在mqx里的
直接用就可以了。

出0入0汤圆

 楼主| 发表于 2015-1-12 22:24:26 | 显示全部楼层
sblpp 发表于 2015-1-12 21:55
谁说的?
rtcs集成在mqx里的
直接用就可以了。

能用不等于免费,盗版Windows也能免费用。
请看官网http://www.freescale.com/zh-Hans ... =Buy_Parametric_Tab
人民币31,034.00

出0入0汤圆

发表于 2015-1-27 11:07:26 | 显示全部楼层
可以做https不

出0入0汤圆

发表于 2015-1-27 11:25:07 | 显示全部楼层
对内存要求多少?

出0入0汤圆

 楼主| 发表于 2015-1-27 12:35:16 | 显示全部楼层
lininglive 发表于 2015-1-27 11:25
对内存要求多少?

取决于要处理网页请求大小和网页请求处理方法

出0入0汤圆

发表于 2015-1-27 15:09:57 | 显示全部楼层
不知道为什么RTCS这么贵,不知道FSL有没有便宜一点的解决方案。

出0入0汤圆

发表于 2015-1-27 15:39:32 | 显示全部楼层
这种小的web server没啥意思啊

出0入0汤圆

 楼主| 发表于 2015-1-27 15:48:53 | 显示全部楼层
Juggernaut 发表于 2015-1-27 15:39
这种小的web server没啥意思啊

这个是WebClient 可以连接服务器的

出0入0汤圆

发表于 2015-1-27 17:16:24 | 显示全部楼层
superrf 发表于 2015-1-27 15:48
这个是WebClient 可以连接服务器的

client还不错的

出0入0汤圆

发表于 2016-3-9 11:43:03 | 显示全部楼层
qs6361036 发表于 2015-1-12 21:32
是的  ,外接ENC28J60 比较常见 !

enc28j60存在发送接收逻辑的bug,让我头疼了一阵子,现在已经解决了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 03:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表