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

使用到的知识点为Linux网络编程里的使用 UDP做DNS解析使用CJSON解析字符串

这个部分的HTTP客户端是从零开始、基于底层 Socket API手写的,而没有依赖 libcurl 等高层HTTP库,使用的是心知天气的API

天气api数据获取流程

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

  1. DNS解析: 使用 gethostbyname() 函数将API的域名 (如 api.seniverse.com) 解析成IP地址。这是建立TCP连接的第一步
  2. 建立TCP连接: 使用 socket() 创建套接字,然后 connect() 到服务器的IP地址和HTTP标准端口(80)
  3. 手动拼接HTTP报文: 根据心知天气API官方定义,我们使用 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

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