为了丰富智能家居的功能,本项目集成了第三方网络API,例如用于获取实时天气信息。相关实现代码位于 obj/http/weather.c
。
1. 实现方式:底层Socket编程
- 一个显著的特点是,本项目的HTTP客户端是从零开始、基于底层BSD Socket API手写的,而没有依赖
libcurl
等高层HTTP库。这在资源受限的嵌入式环境中是一种常见的做法。
2. 核心流程
sh_weather_fetch_now
函数完整地展示了一个手动构造并执行HTTP GET请求的流程:
- DNS解析: 使用
gethostbyname()
函数将API的域名 (如api.seniverse.com
) 解析成IP地址。这是建立TCP连接的第一步。 - 建立TCP连接: 使用
socket()
创建套接字,然后connect()
到服务器的IP地址和HTTP标准端口(80)。 - 手动拼接HTTP报文: 在一个字符数组中,使用
snprintf()
手动拼接出符合HTTP/1.1规范的GET请求报文,包括请求行、Host
头和Connection: close
头。 - 发送请求: 使用
write()
将拼接好的请求报文通过套接字发送出去。 - 接收响应: 使用一个循环和
read()
来不断从套接字读取服务器返回的数据,直到读取完成。 - 解析响应:
- 首先,通过
strstr(buf, "\r\n\r\n")
找到HTTP头和响应体的分隔符,从而定位到真正的JSON数据。 - 然后,使用
cJSON
库来解析JSON字符串,并通过cJSON_GetObjectItem
等函数逐层提取出所需的天气信息字段(如location
,text
,temperature
)。
- 首先,通过
这种实现方式虽然比使用库更复杂,但提供了最大的控制力,并且减少了项目的外部依赖。