为了丰富智能家居的功能,本项目集成了第三方网络API,例如用于获取实时天气信息。相关实现代码位于 obj/http/weather.c

1. 实现方式:底层Socket编程

  • 一个显著的特点是,本项目的HTTP客户端是从零开始、基于底层BSD Socket API手写的,而没有依赖 libcurl 等高层HTTP库。这在资源受限的嵌入式环境中是一种常见的做法。

2. 核心流程

sh_weather_fetch_now 函数完整地展示了一个手动构造并执行HTTP GET请求的流程:

  1. DNS解析: 使用 gethostbyname() 函数将API的域名 (如 api.seniverse.com) 解析成IP地址。这是建立TCP连接的第一步。
  2. 建立TCP连接: 使用 socket() 创建套接字,然后 connect() 到服务器的IP地址和HTTP标准端口(80)。
  3. 手动拼接HTTP报文: 在一个字符数组中,使用 snprintf() 手动拼接出符合HTTP/1.1规范的GET请求报文,包括请求行、Host 头和 Connection: close 头。
  4. 发送请求: 使用 write() 将拼接好的请求报文通过套接字发送出去。
  5. 接收响应: 使用一个循环和 read() 来不断从套接字读取服务器返回的数据,直到读取完成。
  6. 解析响应:
    • 首先,通过 strstr(buf, "\r\n\r\n") 找到HTTP头和响应体的分隔符,从而定位到真正的JSON数据。
    • 然后,使用 cJSON 库来解析JSON字符串,并通过 cJSON_GetObjectItem 等函数逐层提取出所需的天气信息字段(如 location, text, temperature)。

这种实现方式虽然比使用库更复杂,但提供了最大的控制力,并且减少了项目的外部依赖。