lwIP 调用远程服务器 API

lwIP call remote server API

这个问题会比较笼统,因为我什至还没有开始编码,只是想知道是否可以用 lwIP 实现我想要的。

我想要的是让我的嵌入式 STM32F769I-Disco 板调用网站 URL API,例如http://test.com/items/1,returns JSON,然后我想解析它。

由于 lwIP 实现了一个 TCP/IP 堆栈,这在理论上应该是可行的,还是我弄错了?

我还没有真正找到任何可以做到这一点的例子,或者我什至不知道如何搜索它。有什么有用的建议吗?

还有一个问题,我是否应该使用套接字连接而不是尝试调用 API url?如果我决定使用像 nanopb 这样的东西,我是否还需要 lwIP,或者我可以不用它吗?

从浏览 ST 网站来看,如果您愿意花一些时间来了解该平台,那么您所问的问题绝对是可能的。 ST 似乎发布了一个名为 STM32CubeF7. If you scroll down that link to the "User Manuals" section you'll see "UM1713: Developing applications on STM32Cube with lwIP TCP/IP stack" 的支持您的平台的软件开发堆栈,这听起来完全符合您的要求。

退一步说,正如您在问题中提到的,REST-ful 网站 API 通常实现为支持各种操作(GET、POST 等)的 HTTP URL。然而,HTTP 位于协议栈 TCP/IP 之上,并使用 TCP/IP 连接来传输数据 to/from 远程端点。 lwIP 似乎不提供 HTTP 客户端,因此您需要使用另一个库,但是有很多 GitHub 项目可以做到这一点。我最近写了一篇关于用 C++ 实现简单 HTTP 客户端的文章 blog post and codecast,它可能会提供一些见解并帮助阻止您自己动手。

关于你的最后一段,当谈到 "sockets" 时,人们通常指的是 TCP/IP(或 UDP/IP)套接字,所以是的,你仍然需要 lwIP。在这种情况下,Nanopb 将取代 HTTP。

从服务器检索数据涉及到使用 TCP 或 UDP,因此它不仅是 "theoretically possible",它是您的浏览器从 Web 服务器接收数据的实际方式:通过打开 TCP/IP 连接到服务器的端口 80.

UDP 不适用于从服务器接收数据,因为它是无连接的,并且不保证数据包会按顺序接收,或者根本不会接收。对于 TCP,它是 "all or nothing" - 要么您将按顺序接收所有数据包,要么套接字将在某个时刻关闭,因为发送方的缓冲区被未确认的数据包填满。

因此 HTTP 将使用 TCP/IP,这是肯定的,您需要执行以下几个步骤:

  1. 使用 lwip 为您的 www.test.com 网站创建 DNS 查找。
  2. 使用 lwip 打开一个 TCP/IP 到 IP 地址的连接,可能是端口 80。
  3. recv 回调函数(以及其他函数)附加到 lwip,每当收到数据包时,Lwip 都会调用该回调函数。您还想知道套接字是否在对话期间关闭,因此请确保注册所有回调。
  4. 向端口 80 发送一个 HTTP request 字符串。您基本上是向打开的 TCP 套接字发送一个字符串。这可能很简单:

    GET /items/1 HTTP/1.1
    Host: www.test.com
    <crlf>
    

    最后的<crlf>是一个空行,它标志着HTTP请求的结束。

  5. 您的 recv 函数将接受来自服务器的传入数据包,并将它们写入 FIFO 缓冲区以供进一步处理。不能保证您会在一个数据包中获得整个 HTTP 响应,所以不要指望一次性处理它们,除非负载真的很短,中间没有代理,并且您总体上感到幸运。

  6. 因此,您需要在传入数据到达时对其进行解析。其中一个 HTTP headers 会给你整个响应的长度,否则你将需要处理 chunked encoding。这是您可能从服务器获得的响应示例(在一个或多个 TCP 数据包中):

    HTTP/1.1 200 OK
    Date: Mon, 23 Aug 2017 22:38:34 GMT
    Content-Type: text/html; charset=UTF-8
    Content-Encoding: UTF-8
    Content-Length: 18
    
    { 
        "value":5, 
        "something_else": [0, 1, 2] 
    }
    

    注意 headers 和负载开始之间的空 new-line。

  7. 一旦你解析了所有 headers 并到达 JSON,那么你可能会使用现有的 C 库来解析 JSON,这也将可能需要一些工作才能理解。从开发的角度来看,用 Protocol Buffers 替换这最后一步可能是一个明智的想法(C 端的工作可能更少),但该协议的可移植性不如 JSON(尽管肯定更小)。