httpclient_sample.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * File : httpclient.c
  3. *
  4. * Copyright (c) 2006-2022, RT-Thread Development Team
  5. *
  6. * SPDX-License-Identifier: Apache-2.0
  7. *
  8. * Change Logs:
  9. * Date Author Notes
  10. * 2018-07-20 flybreak first version
  11. * 2018-09-05 flybreak Upgrade API to webclient latest version
  12. */
  13. #include <webclient.h> /* 使用 HTTP 协议与服务器通信需要包含此头文件 */
  14. #include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */
  15. #include <netdb.h>
  16. #include <cJSON.h>
  17. #include <finsh.h>
  18. #define GET_HEADER_BUFSZ 1024 //头部大小
  19. #define GET_RESP_BUFSZ 1024 //响应缓冲区大小
  20. #define GET_URL_LEN_MAX 256 //网址最大长度
  21. #define GET_URI "http://mobile.weather.com.cn/data/sk/%s.html" //获取天气的 API
  22. #define AREA_ID "101021300" //上海浦东地区 ID
  23. /* 天气数据解析 */
  24. void weather_data_parse(rt_uint8_t *data)
  25. {
  26. cJSON *root = RT_NULL, *object = RT_NULL, *item = RT_NULL;
  27. root = cJSON_Parse((const char *)data);
  28. if (!root)
  29. {
  30. rt_kprintf("No memory for cJSON root!\n");
  31. return;
  32. }
  33. object = cJSON_GetObjectItem(root, "sk_info");
  34. item = cJSON_GetObjectItem(object, "cityName");
  35. rt_kprintf("\ncityName:%s ", item->valuestring);
  36. item = cJSON_GetObjectItem(object, "temp");
  37. rt_kprintf("\ntemp :%s ", item->valuestring);
  38. item = cJSON_GetObjectItem(object, "wd");
  39. rt_kprintf("\nwd :%s ", item->valuestring);
  40. item = cJSON_GetObjectItem(object, "ws");
  41. rt_kprintf("\nws :%s ", item->valuestring);
  42. item = cJSON_GetObjectItem(object, "sd");
  43. rt_kprintf("\nsd :%s ", item->valuestring);
  44. item = cJSON_GetObjectItem(object, "date");
  45. rt_kprintf("\ndate :%s", item->valuestring);
  46. item = cJSON_GetObjectItem(object, "time");
  47. rt_kprintf("\ntime :%s \n", item->valuestring);
  48. if (root != RT_NULL)
  49. cJSON_Delete(root);
  50. }
  51. void weather(int argc, char **argv)
  52. {
  53. rt_uint8_t *buffer = RT_NULL;
  54. int resp_status;
  55. struct webclient_session *session = RT_NULL;
  56. char *weather_url = RT_NULL;
  57. int content_length = -1, bytes_read = 0;
  58. int content_pos = 0;
  59. /* 为 weather_url 分配空间 */
  60. weather_url = rt_calloc(1, GET_URL_LEN_MAX);
  61. if (weather_url == RT_NULL)
  62. {
  63. rt_kprintf("No memory for weather_url!\n");
  64. goto __exit;
  65. }
  66. /* 拼接 GET 网址 */
  67. rt_snprintf(weather_url, GET_URL_LEN_MAX, GET_URI, AREA_ID);
  68. /* 创建会话并且设置响应的大小 */
  69. session = webclient_session_create(GET_HEADER_BUFSZ);
  70. if (session == RT_NULL)
  71. {
  72. rt_kprintf("No memory for get header!\n");
  73. goto __exit;
  74. }
  75. /* 发送 GET 请求使用默认的头部 */
  76. if ((resp_status = webclient_get(session, weather_url)) != 200)
  77. {
  78. rt_kprintf("webclient GET request failed, response(%d) error.\n", resp_status);
  79. goto __exit;
  80. }
  81. /* 分配用于存放接收数据的缓冲 */
  82. buffer = rt_calloc(1, GET_RESP_BUFSZ);
  83. if (buffer == RT_NULL)
  84. {
  85. rt_kprintf("No memory for data receive buffer!\n");
  86. goto __exit;
  87. }
  88. content_length = webclient_content_length_get(session);
  89. if (content_length < 0)
  90. {
  91. /* 返回的数据是分块传输的. */
  92. do
  93. {
  94. bytes_read = webclient_read(session, buffer, GET_RESP_BUFSZ);
  95. if (bytes_read <= 0)
  96. {
  97. break;
  98. }
  99. }while (1);
  100. }
  101. else
  102. {
  103. do
  104. {
  105. bytes_read = webclient_read(session, buffer,
  106. content_length - content_pos > GET_RESP_BUFSZ ?
  107. GET_RESP_BUFSZ : content_length - content_pos);
  108. if (bytes_read <= 0)
  109. {
  110. break;
  111. }
  112. content_pos += bytes_read;
  113. }while (content_pos < content_length);
  114. }
  115. /* 天气数据解析 */
  116. weather_data_parse(buffer);
  117. __exit:
  118. /* 释放网址空间 */
  119. if (weather_url != RT_NULL)
  120. rt_free(weather_url);
  121. /* 关闭会话 */
  122. if (session != RT_NULL)
  123. webclient_close(session);
  124. /* 释放缓冲区空间 */
  125. if (buffer != RT_NULL)
  126. rt_free(buffer);
  127. }
  128. MSH_CMD_EXPORT(weather, Get weather by webclient);