为了丰富智能家居的功能,本项目集成了第三方网络API,例如用于获取实时天气信息。相关实现代码位于 obj/http/weather.c
使用到的知识点为Linux网络编程里的使用 UDP做DNS解析 和 使用CJSON解析字符串
这个部分的HTTP客户端是从零开始、基于底层 Socket API手写的,而没有依赖 libcurl 等高层HTTP库,使用的是心知天气的API
天气api数据获取流程
sh_weather_fetch_now 函数完整地展示了一个手动构造并执行HTTP GET请求的流程:
- DNS解析: 使用
gethostbyname()函数将API的域名 (如api.seniverse.com) 解析成IP地址。这是建立TCP连接的第一步 - 建立TCP连接: 使用
socket()创建套接字,然后connect()到服务器的IP地址和HTTP标准端口(80) - 手动拼接HTTP报文: 根据心知天气API官方定义,我们使用
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)
- 首先,通过
这种实现方式虽然比使用库更复杂,但提供了最大的控制力,并且减少了项目的外部依赖