Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread发布
Webclient
感觉webclient里的webclient_file存在内存泄漏
发布于 2019-10-31 17:35:49 浏览:1966
订阅该版
之前用webclient-master时候遇到过内存泄漏,现在整理工程改成固定版本webclient-v2.1.0,感觉还是有泄漏现象,官方代码库更新一下把Bug去掉吧! 2019.07月份的笔记 —————————————————————————————————— 貌似存在内存泄漏 ``` msh />free total memory: 56464 used memory : 27472 maximum allocated memory: 30840 msh />web_post_file_test [D/web] host address: 192.168.137.1 , port: 880 [D/web] request header: [D/web] GET /web_upload/ HTTP/1.1 [D/web] Host: 192.168.137.1 [D/web] User-Agent: RT-Thread HTTP Agent msh />free total memory: 56464 used memory : 31580 maximum allocated memory: 49408 msh />web_post_file_test [D/web] host address: 192.168.137.1 , port: 880 [D/web] request header: [D/web] GET /web_upload/ HTTP/1.1 [D/web] Host: 192.168.137.1 [D/web] User-Agent: RT-Thread HTTP Agent msh />free total memory: 56464 used memory : 35688 maximum allocated memory: 53516 msh />web_post_file_test [D/web] host address: 192.168.137.1 , port: 880 [D/web] request header: [D/web] GET /web_upload/ HTTP/1.1 [D/web] Host: 192.168.137.1 [D/web] User-Agent: RT-Thread HTTP Agent [E/at.skt] no memory for esp8266 device(esp0) URC receive buffer(2920). msh /> ``` 首先是发现 webclient_post_file 中在初始化 `session->header` 时没有处理 `session->header->length` ```c //int webclient_post_file(const char* URI, const char* filename, const char* form_data) session->header->buffer = web_strdup(header);//附近没有session->header->length有关的代码 ``` 之后发现 `session->header->buffer = web_strdup(header); `语句貌似很危险 尝试按`web_post_test`调用的`webclient_post_comm`的方式初始化header 解决了之前怀疑的内存泄漏的问题 接下来比较Fiddler向MVC发的File抓包,发现`“Content-Length:”`是在`“boundary”`里面的,遂改之 ```c /** * post file to http server. * * @param URI input server address * @param filename post data filename * @param form_data form data * * @return <0: POST request failed * =0: success */ #define webclient_post_file_backup (0) int webclient_post_file(const char* URI, const char* filename, const char* form_data) { size_t length; char boundary[60]; int fd = -1, rc = WEBCLIENT_OK; unsigned char *buffer = RT_NULL, *buffer_ptr; struct webclient_session* session = RT_NULL; fd = open(filename, O_RDONLY, 0); if (fd < 0) { LOG_D("post file failed, open file(%s) error.", filename); rc = -WEBCLIENT_FILE_ERROR; goto __exit; } /* get the size of file */ length = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); buffer = (unsigned char *) web_malloc(WEBCLIENT_RESPONSE_BUFSZ); if (buffer == RT_NULL) { LOG_D("post file failed, no memory for response buffer."); rc = -WEBCLIENT_NOMEM; goto __exit; } #if webclient_post_file_backup char *header = RT_NULL; header = (char *) web_malloc(WEBCLIENT_HEADER_BUFSZ); if (header == RT_NULL) { LOG_D("post file failed, no memory for header buffer."); rc = -WEBCLIENT_NOMEM; goto __exit; } rt_memset(header,0,WEBCLIENT_HEADER_BUFSZ); #endif /* build boundary */ rt_snprintf(boundary, sizeof(boundary), "----------------------------%012d", rt_tick_get()); /* build encapsulated mime_multipart information*/ buffer_ptr = buffer; /* first boundary */ buffer_ptr += rt_snprintf((char*) buffer_ptr, WEBCLIENT_RESPONSE_BUFSZ - (buffer_ptr - buffer), "--%s
", boundary); buffer_ptr += rt_snprintf((char*) buffer_ptr, WEBCLIENT_RESPONSE_BUFSZ - (buffer_ptr - buffer), "Content-Disposition: form-data; %s
", form_data); buffer_ptr += rt_snprintf((char*) buffer_ptr, WEBCLIENT_RESPONSE_BUFSZ - (buffer_ptr - buffer), //"Content-Type: application/octet-stream
"); "Content-Type: image/jpeg
"); /* calculate content-length */ length += buffer_ptr - buffer; length += rt_strlen(boundary) + 6; /* add the last boundary */ #if webclient_post_file_backup /* build header for upload */ char *header_ptr; header_ptr = header; header_ptr += rt_snprintf(header_ptr, WEBCLIENT_HEADER_BUFSZ - (header_ptr - header), "Content-Length: %d
", length); header_ptr += rt_snprintf(header_ptr, WEBCLIENT_HEADER_BUFSZ - (header_ptr - header), "Content-Type: multipart/form-data; boundary=%s
", boundary); session = webclient_session_create(WEBCLIENT_HEADER_BUFSZ); if(session == RT_NULL) { rc = -WEBCLIENT_NOMEM; goto __exit; } session->header->buffer = web_strdup(header); //session->header->length = (size_t)(-1); #else /* build header for upload */ session = webclient_session_create(WEBCLIENT_HEADER_BUFSZ); if(session == RT_NULL) { rc = -WEBCLIENT_NOMEM; goto __exit; } //session->header->buffer = web_strdup(header); //调整"Content-Length:"到boundary内部 webclient_header_fields_add(session, "Content-Type: multipart/form-data; boundary=%s
", boundary); webclient_header_fields_add(session, "Content-Length: %d
", length); #endif rc = webclient_post(session, URI, NULL); rt_thread_mdelay(100); if( rc< 0) { goto __exit; } /* send mime_multipart */ webclient_write(session, buffer, buffer_ptr - buffer); rt_thread_mdelay(100); /* send file data */ while (1) { length = read(fd, buffer, WEBCLIENT_RESPONSE_BUFSZ); if (length <= 0) { break; } webclient_write(session, buffer, length); rt_thread_mdelay(100); } /* send last boundary */ rt_snprintf((char*) buffer, WEBCLIENT_RESPONSE_BUFSZ, "
--%s--
", boundary); webclient_write(session, buffer, rt_strlen(boundary) + 6); __exit: if (fd >= 0) { close(fd); } if (session != RT_NULL) { webclient_close(session); } if (buffer != RT_NULL) { web_free(buffer); } #if webclient_post_file_backup if (header != RT_NULL) { web_free(header); } #endif return 0; } ```
查看更多
1
个回答
默认排序
按发布时间排序
wuguifang
2024-02-05
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考
你是怎么调用成功的,我用demo里面的没有调用成功,这个是我提出的问题的链接: - [如何使用webclient里面的post方法发送文件](https://club.rt-thread.org/ask/question/1816db98255e6841.html)
撰写答案
登录
注册新账号
关注者
0
被浏览
2k
关于作者
moneng
这家伙很懒,什么也没写!
提问
5
回答
18
被采纳
0
关注TA
发私信
相关问题
1
RT-Thread单内核v0.2.2正式版
2
[发布] RT-Thread RTOS v0.2.3版本
3
RT-Thread 0.3.0 beta
4
RT-Thread/STM32 0.3.0 RC1发布
5
RT-Thread/LM3S 0.3.0 RC1版发布
6
建议弄个MIPS版本的。龙芯上用。
7
开源实时操作系统RT-Thread 0.3.0正式版发布
8
关于RT-THREAD的UDP讨论
9
这里是BUG回报板块!
10
rt-thread stm32 0.3.0 rc1 网络问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
组件 lwip v2.0.3 版本使用 netdev网卡的 ping 功能
2
简单两步配置RTT源码阅读环境 vsc+clangd
3
恩智浦[FRDM-MCXN947]初探 之 ADC与DAC
4
LVGL使用字库IC芯片显示中文
5
基于STM32H750和Rt-Thread的CANFD通信实现的记录(一)
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
线程
RT-Thread Nano
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
807
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
1
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部