Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
关于WebClient&tls组件的几个问题
发布于 2018-08-22 16:45:27 浏览:2736
订阅该版
* 本帖最后由 slyant 于 2018-8-22 16:47 编辑 * 1.WebClient组件启用WEBCLIENT_USING_TLS后,编译有几个错误: (1)webclient.c中webclient_open_tls未定义,原因是webclient_open_tls的定义在使用之后,且未在头文件中声明,应在webclient.h中添加声明: #ifdef WEBCLIENT_USING_TLS int webclient_open_tls(struct webclient_session * session, const char *URI); #endif (2)tls_net.c中fcntl未定义,原因是#include
被条件编译排除掉了。增加#include
可编译通过 2.webclient.c中定义了webclient_strdup函数(和RTT中定义的几乎相同),但文件中混用了webclient_strdup和rt_strdup,代码不够严谨。 还有webclient.c使用了strlen而不是rt_strlen,使用了memcpy而不是rt_memcpy,还有memset以及一些字符操作都没有使用rt_的。其实这个webclient_strdup完全可以使用rt_strdup替代。 3.启用WEBCLIENT_USING_TLS,访问[https://www.apiopen.top/weatherApi?city=](https://www.apiopen.top/weatherApi?city=)武汉 ![0001.png](/uploads/201808/22/150550y0zbbsth33ikdozn.png) 使用Postman访问结果: ![0006.png](/uploads/201808/22/160553pqq2zujpcv77r6ec.png) 修改获取天气的例子,主要修改json解析的部分: ```
#include
/* 使用 HTTP 协议与服务器通信需要包含此头文件 */ #include
/* 使用BSD socket,需要包含socket.h头文件 */ #include
#include
#define BUF_SZ 4096 //缓冲区大小 #define URL_LEN_MAX 256 //网址最大长度 static const char* URL = "https://www.apiopen.top/weatherApi?city=%s"; void weather_data_parse(rt_uint8_t *data) { rt_kprintf("%s
", data); } void weather(int argc, char **argv) { rt_uint8_t *ptr = RT_NULL; int length = 0, result; struct webclient_session *session = RT_NULL; char *weather_url = RT_NULL; char* city_name = "武汉"; if(argc>=2) { city_name = argv[1]; } /* 为 weather_url 分配空间 */ weather_url = rt_calloc(1, URL_LEN_MAX); if (!weather_url) { rt_kprintf("No memory for weather_url!
"); goto __exit; } /* 拼接 GET 网址 */ rt_snprintf(weather_url, URL_LEN_MAX, URL, city_name); rt_kprintf(weather_url); /* 为结构体 webclient_session 分配空间 */ session = (struct webclient_session *)rt_calloc(1, sizeof(struct webclient_session)); if (!session) { rt_kprintf("No memory for session structure!
"); goto __exit; } /* 连接天气网站 */ result = webclient_connect(session, weather_url); if (result < 0) { rt_kprintf("Webclient connect URI(%s) failed!
", weather_url); goto __exit; } /* 发送官方标准 header */ result = webclient_send_header(session, WEBCLIENT_GET, RT_NULL, RT_NULL); if (result < 0) { rt_kprintf("Webclient send header buffer failed return %d!", result); goto __exit; } /* 检查响应 */ if (webclient_handle_response(session)) { if (session->response != 200) { rt_kprintf("webclient handle response(%d) error!", session->response); goto __exit; } } /* 分配用于存放接收数据的缓冲 */ ptr = rt_calloc(1, BUF_SZ); if(!ptr) { rt_kprintf("No memory for data receive buffer!
"); goto __exit; } length = webclient_read(session, ptr, BUF_SZ); ptr[length] = '\0'; /* 天气数据解析 */ weather_data_parse(ptr); __exit: /* 释放网址空间 */ if (weather_url != RT_NULL) rt_free(weather_url); /* 关闭会话 */ if (session != RT_NULL) webclient_close(session); /* 释放缓冲区空间 */ if (ptr != RT_NULL) rt_free(ptr); } #ifdef FINSH_USING_MSH #include
MSH_CMD_EXPORT(weather, Get weather by webclient); #endif
``` 运行结果:![0002.png](/uploads/201808/22/151510z715b44kc8877jv6.png) 在webclient.c的webclient_connect函数的如下代码: ```
/* Check valid IP address and URL */ rc = webclient_resolve_address(session, &res, URI, &request); if (rc != WEBCLIENT_OK) { goto _exit; } if (!res) { rc = -1; goto _exit; } /* copy host address */ if (*request) session->request = webclient_strdup(request); else session->request = RT_NULL;
```在上面代码后面添加调试输出host,port,request信息: ```
/* Check valid IP address and URL */ rc = webclient_resolve_address(session, &res, URI, &request); if (rc != WEBCLIENT_OK) { goto _exit; } if (!res) { rc = -1; goto _exit; } /* copy host address */ if (*request) session->request = webclient_strdup(request); else session->request = RT_NULL; //session->tls_session->host = webclient_strdup("www.apiopen.top"); //session->tls_session->port = webclient_strdup("443"); //session->request = webclient_strdup("/weatherApi?city=武汉"); rt_kprintf("host:%s.
",session->tls_session->host); rt_kprintf("port:%s.
",session->tls_session->port); rt_kprintf("request:%s.
",session->request);
```运行结果: ![0003.png](/uploads/201808/22/153203f79cf66ka386b47f.png) 注释掉Check valid IP address and URL的部分,手动赋值host,port,request,代码如下: ```
/* Check valid IP address and URL */ // rc = webclient_resolve_address(session, &res, URI, &request); // if (rc != WEBCLIENT_OK) // { // goto _exit; // } // if (!res) // { // rc = -1; // goto _exit; // } // /* copy host address */ // if (*request) // session->request = webclient_strdup(request); // else // session->request = RT_NULL; session->tls_session->host = webclient_strdup("www.apiopen.top"); session->tls_session->port = webclient_strdup("443"); session->request = webclient_strdup("/weatherApi?city=武汉"); rt_kprintf("host:%s.
",session->tls_session->host); rt_kprintf("port:%s.
",session->tls_session->port); rt_kprintf("request:%s.
",session->request);
```运行结果: ![0004.png](/uploads/201808/22/155653ff80ugf0riuuz6f4.png)返回404的错误。但起码连接和认证成功了。 这就显得有点奇怪了,webclient_resolve_address函数并没有解析错,但用它就是不行了呢? 内存分配情况如下: thread pri status sp stack size max used left tick error ------ --- ------- ---------- ---------- ------ ---------- --- tshell 20 ready 0x00000140 0x00007800 13% 0x00000003 000 tcpip 10 suspend 0x000000c4 0x00000400 80% 0x00000002 000 etx 12 suspend 0x00000094 0x00000400 14% 0x00000010 000 erx 12 suspend 0x00000094 0x00000400 52% 0x00000009 000 tidle 31 ready 0x00000054 0x00000100 34% 0x00000005 000 msh />free total memory: 33554400 used memory : 240408 maximum allocated memory: 292848 msh /> 另说明一下,这个API即使city参数不正确,也应该返回json,使用Postman访问结果如下图: ![0005.png](/uploads/201808/22/160304bhps4np8yhnyc6tu.png) 另外还有2个问题: 1.使用正点原子阿波罗STM32F429开发板,驱动了以太网卡,连接网线,ifconfig可以看到从DHCP获取到动态IP,也可以Ping通。但发现一个问题,如果启动时,网上绿色灯不亮,则不论等待多长时间,也不会获取到IP。复位1到3次,一般都可以获取到IP。也就是说启动过程中如果没能获取到IP,则后面就没法连接了? 2.启动后过一段时间(大概几分钟),就输出![0006.png](/uploads/201808/22/164659n8tb4sv1byzzabt4.png)
查看更多
3
个回答
默认排序
按发布时间排序
aozima
2018-08-22
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
楼主研究得很深入啊,点个赞!
Cheney_Chen
2018-08-22
这家伙很懒,什么也没写!
首先,通楼主上述描述可以知道,楼主使用的是webclient V1.0.0版本,不知道楼主是否注意 webclient 有最新版本更新,最新版本在多个方面都做了优化处理,对上述部分问题也做了处理,因为对 1.0.0 的接口和实现改动比较大,所以可能还没有普及使用。 然后是提到的几个问题: 1. webclient_open_tls 函数定义是静态内部函数,不对外开放,所以不会在 webclient.h 给出; 2. strdup 函数问题已经在新版本中统一修改,webclient 新版本对函数定义、日志、注释等方面都有统一修改; 3. mbestls 这个问题,看情况是因为在 mbedtls 中域名解析的时候出问题了,这可能和 LWIP 中一个配置有关,可以尝试修改搜索 LWIP 中的 `MEMP_NUM_NETDB` 定义,将默认的 1 改为 2-4 再试着运行例程,这也是历史遗留问题。 4.其他问题未知,需要楼主进一步调试确定问题。
slyant
2018-08-27
这家伙很懒,什么也没写!
今天得空,按照 [https://www.rt-thread.org/qa/space-uid-10447.html](Cheney_Chen)的解决方案做了修改: 1.webclient版本确实是用的V1.0.0版本,修改为最新版本后,解决大部分问题。 2.使用最新的版本,然后需要修改lwip\opt.h文件的MEMP_NUM_NETDB宏定义值为>1的值,否则https的URL的解析会失败,MEMP_NUM_NETDB的大概意思是lwip_addrinfo()占用的内存释放前能够被并发调用的数量。 写了一个https查询天气的例子,我单独发贴: 使用WebClient&tls获取实时天气 - RT-Thread组件 - RT-Thread开发者社区 - Powered by Discuz! [https://www.rt-thread.org/qa/forum.php?mod=viewthread&tid=7884&page=1&extra=#pid37446](https://www.rt-thread.org/qa/forum.php?mod=viewthread&tid=7884&page=1&extra=#pid37446) 另外还有2个问题: 1.使用正点原子阿波罗STM32F429开发板,驱动了以太网卡,连接网线,ifconfig可以看到从DHCP获取到动态IP,也可以Ping通。但发现一个问题,如果启动时,网卡绿色灯不亮,则不论等待多长时间,也不会获取到IP。复位1到3次,一般都可以获取到IP。也就是说启动过程中如果没能获取到IP,则后面就没法连接了?连接的过程大概在[I/SAL_SOC] Socket Abstraction Layer initialize success.这个过程一过,就没法再获取到IP的? 2.启动后过一段时间(大概几分钟),就输出 ![115,0](https://www.rt-thread.org/qa/data/attachment/forum/201808/22/164659n8tb4sv1byzzabt4.png) ,跟踪了一下代码,大概是-RT_EFULL,是邮箱满了?什么原因? ``` /* for non-blocking call */ if (mb->entry == mb->size && timeout == 0) { rt_hw_interrupt_enable(temp); return -RT_EFULL; } /* mailbox is full */ while (mb->entry == mb->size) { /* reset error number in thread */ thread->error = RT_EOK; /* no waiting, return timeout */ if (timeout == 0) { /* enable interrupt */ rt_hw_interrupt_enable(temp); return -RT_EFULL; } ```
撰写答案
登录
注册新账号
关注者
0
被浏览
2.7k
关于作者
slyant
这家伙很懒,什么也没写!
提问
10
回答
28
被采纳
0
关注TA
发私信
相关问题
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
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
在用clangd开发RTT吗,快来试试如何简单获得清晰干净的工作区
2
GD32F450 片内 flash驱动适配
3
STM32H7R7运行CherryUSB
4
RT-Smart首次线下培训,锁定2024 RT-Thread开发者大会!
5
使用RC522软件包驱动FM1722
热门标签
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
freemodbus
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
中断
编译报错
Debug
SFUD
rt_mq_消息队列_msg_queue
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
a1012112796
10
个答案
1
次被采纳
踩姑娘的小蘑菇
4
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
Ryan_CW
4
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
6
次点赞
YZRD
2
篇文章
5
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
Woshizhapuren
1
篇文章
5
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部