Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread发布
感觉webclient里的webclient_file存在内存泄漏
发布于 2019-10-31 17:35:49 浏览:1288
订阅该版
* 本帖最后由 moneng 于 2019-10-31 17:38 编辑 * 之前用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 ```//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”里面的,遂改之```/** * 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; }```
查看更多
0
个回答
默认排序
按发布时间排序
暂无答案,快来添加答案吧
撰写答案
登录
注册新账号
关注者
0
被浏览
1.3k
关于作者
moneng
这家伙很懒,什么也没写!
提问
5
回答
16
被采纳
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
五分钟玩转RT-Thread新社区
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
6
国产MCU移植系列教程汇总,欢迎查看!
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
RT-Thread 框架下的 SMP 支持
2
RISC-V上下文切换汇编代码注释
3
RT-Thread中Lan8720和lwip协议栈的使用
4
RT-Smart riscv64汇编注释
5
【NXP】LPC55S69-RT-Thread Micropython移植日志
热门标签
RT-Thread Studio
串口
LWIP
SPI
Env
AT
FinSH
ART-Pi
Bootloader
CAN总线
Hardfault
文件系统
USB
DMA
RT-Thread
线程
stm32
RT-Thread Nano
SCons
MQTT
ESP8266
ota
UART
packages_软件包
rtthread
I2C
RTC
freemodbus
flash
cubemx
rt-smart
W5500
定时器
FAL
PWM
ADC
BSP
SDIO
msh
AB32VG1
socket
Debug
C++_cpp
SFUD
中断
编译报错
MicroPython
keil
LVGL
dfs
本月问答贡献
RTT_逍遥
3
个答案
2
次被采纳
xiaorui
5
个答案
1
次被采纳
crystal266
5
个答案
1
次被采纳
用户名由3_15位
4
个答案
1
次被采纳
小小李sunny
2
个答案
1
次被采纳
本月文章贡献
YZRD
4
篇文章
9
次点赞
牧尘
2
篇文章
3
次点赞
RTT_逍遥
1
篇文章
10
次点赞
Digiproto
1
篇文章
6
次点赞
螺丝松掉的人
1
篇文章
4
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部