12

I'm having hard time to choose the format on which my server and my end points will communicate with.
I am considering:

  • JSON
  • YAML Too hard to parse
  • CSV
  • Google Protobufs
  • Binary packing/unpacking (with no use of casting/memset/memcpy to enable portability)
  • Some form of DSL
  • Any other suggestion you might have

My criterias are ordered from the most important to the least:

  1. Which is the easiest to parse?
  2. Which is the fastest to parse?
  3. Which has the smallest in bytes?
  4. Which has the potential to have the most readable messages?
  5. Which has the potential to be encrypted more easily?
  6. Which has the potential to be compressed more easily?

EDIT to clarify:

  • Are the data transfers bi-directional? Yes.
  • What is the physical transport? Ethernet.
  • Is the data formatted as packets or streams? Both but usually packets.
  • How much RAM do the end-points have? The smallest amount possible, depeands on the format I choose.
  • How big are your data? As big as it needs to be. I won't receive huge datasets though.
  • Does the end-point have an RTOS? No.
4

8 回答 8

5

关键因素是:

  • 你的客户有什么能力?(例如,你能从现成的 XML 解析器中挑选一个吗?由于性能原因,不排除大部分解析器吗?你能即时压缩数据包吗?)
  • 您的数据的复杂性是多少(“扁平化”或深度结构化?)
  • 您需要高频更新吗?部分更新?

在我的经验中:

一个简单的文本协议(将自己归类为 DSL),其接口为

string RunCommand(string commandAndParams)
// e.g. RunCommand("version") returns "1.23"

使许多方面变得更容易:调试、日志记录和跟踪、协议扩展等。为设备提供一个简单的终端/控制台对于跟踪问题、运行测试等非常有用。

让我们详细讨论一下限制,作为其他格式的参考:

  • 客户端需要运行一个微解析器。这并不像听起来那么复杂(我的“微解析器库”的核心是 10 个函数,总共大约 200 行代码),但应该可以进行基本的字符串处理
  • 一个写得不好的解析器是一个很大的攻击面。如果设备是关键/敏感设备,或者预计将在恶劣环境中运行,则实施需要格外小心。(对于其他协议也是如此,但是快速破解的文本解析器很容易出错)
  • 高架。可能受到混合文本/二进制协议或 base64(开销为 37%)的限制。
  • 潜伏。对于典型的网络延迟,您将不希望发出许多小命令,某种批处理请求及其返回的方式会有所帮助。
  • 编码。如果您必须传输无法用 ASCII 表示的字符串,并且不能在两端使用 UTF-8 之类的东西,那么基于文本的协议的优势就会迅速下降。

仅当设备要求、设备处理能力极低(例如,具有 256 字节 RAM 的 USB 控制器)或您的带宽受到严重限制时,我才会使用二进制协议。我使用过的大多数协议都使用它,这很痛苦。

Google protBuf是一种使二进制协议更容易的方法。如果您可以在两端运行库,并且有足够的自由度来定义格式,这是一个不错的选择。

CSV是一种将大量数据打包成易于解析的格式的方法,因此它是文本格式的扩展。但是,它的结构非常有限。只有当您知道您的数据适合时,我才会使用它。

XML/YAML/...我只会在处理能力不成问题、带宽不成问题或者您可以即时压缩并且数据结构非常复杂的情况下使用。JSON 在开销和解析器要求上似乎更轻一些,可能是一个很好的折衷方案。

于 2010-08-04T09:06:49.470 回答
3

首先,看看你能找到什么样的现有库。即使格式难以解析,预先编写的库也可以使格式更具吸引力。最容易解析的格式是您已经拥有解析器的格式。

解析速度通常是二进制格式中最好的。最快的方法之一是使用“平面”二进制格式(读取缓冲区,将指向缓冲区的指针转换为指向数据结构的指针,并通过数据结构访问缓冲区中的数据)。不需要真正的“解析”,因为您正在传输(本质上)内存区域的二进制转储。

要最小化有效负载,请创建针对您的特定需求量身定制的自定义二进制格式。这样,您可以调整各种设计权衡以发挥最大优势。

“可读”是主观的。谁可读?XML 和 CSV 等纯文本格式很容易被人类阅读。平面二进制图像很容易被机器读取。

加密例程通常将要压缩的数据视为一大块二进制数据(它们根本不尝试解释它),因此加密应该同样适用于任何格式的数据。

基于文本的格式(XML、CSV 等)往往是非常可压缩的。二进制格式的可压缩性往往较低,但开始时“浪费”的位较少。

根据我的经验,我在以下方面取得了最好的结果:

  • CSV - 当数据采用可预测、一致的格式时最好。在使用脚本语言(基于文本的 I/O 比二进制 I/O 更容易)进行通信时也很有用。手动轻松生成/解释。
  • Flat binary - 最好将数据结构 (POD) 从一个地方传输到另一个地方。为获得最佳结果,请打包结构以避免使用不同填充的不同编译器出现问题。
  • 自定义格式 - 通常,自设计自定义格式以来的最佳结果可让您平衡灵活性、开销和可读性。不幸的是,从头开始设计自定义格式最终可能比看起来要多得多。
于 2010-08-02T21:33:24.853 回答
3

通常在这些情况下,为设备定制数据格式是值得的。例如,根据您在网络或存储大小方面面临的限制,您可以选择流式压缩或更喜欢完全压缩。此外,您要存储的数据类型也是一个重要因素。

如果你最大的问题是易于解析,你应该选择 xml,但在嵌入式设备上,与传输速度、存储大小和 CPU 消耗相比,易于解析通常不是问题。JSON 和 YAML 与 XML 非常相似,主要侧重于解析的易用性。Protobuf 可能会挤进去,二进制打包是人们通常做的事情。您应该在传输级别上进行加密和压缩,尽管从功能上讲,您的目标应该是在消息中放置尽可能少的信息。

我知道我没有给你一个明确的答案,但我认为这样一个笼统的问题没有这样的事情。

于 2010-08-02T08:28:34.003 回答
2

第一个问题的答案很大程度上取决于您要做什么。我从附加到您的问题的标签中收集到,您的端点是嵌入式系统,而您的服务器是某种类型的 PC。在 PC 上解析 XML 很容易,但在嵌入式系统上则有点困难。您也没有提及您的通信是否是双向的。如果在您的情况下,端点只是将数据传递给服务器,而不是相反,那么 XML 可能工作得很好。如果服务器将数据传递到端点,那么 CSV 或专有二进制格式可能更容易在端点解析。CSV 和 XML 都易于人类阅读。

  • 数据传输是双向的吗?
  • 什么是物理运输?(例如 RS-232、以太网、USB?)
  • 数据格式是数据包还是流?
  • 端点有多少 RAM?你的数据有多大?
  • 端点是否有 RTOS?
于 2010-08-02T20:50:39.123 回答
2

CSV 将在基于 XML 的解决方案之前满足您的需求。非常容易解析,一到两打代码。然后,您添加任何解决方案所需的术语/字段的含义。CSV 的开销非常轻,一些逗号和引号,与 XML 解决方案相比,您经常会发现比实际肉类/数据更多的 XML 标记和语法,对于单个 8 位或 32 位值,通常会烧掉几十到数百个字节。如果您认为与二进制相比需要三个字符(字节)来表示一个 8 位值(hexchar hexchar 逗号),那么授予 CSV 也会有开销。在用于创建和解析以及可能压缩/解压缩的庞大库之上,未压缩的大型 XML 解决方案将消耗相当多的传输带宽和存储空间。CSV 肯定比二进制更容易阅读,而且通常比 XML 更容易,因为 xml 非常冗长,您无法一次在一个屏幕上查看所有相关数据。每个人都可以访问一个好的电子表格工具,gnumeric,openoffice,ms office,这样就可以让 CSV 更容易阅读/使用,gui 已经存在。

虽然没有通用的答案,但您需要对此进行系统工程。您可能非常希望在主机或大型计算机端拥有 JSON/XML 并转换为其他格式(如二进制)进行传输,然后在嵌入式端可能根本不需要 ASCII,也无需浪费精​​力它,获取二进制数据并使用它。我也不知道您对嵌入式的定义,我假设因为您在谈论 ascii 格式,所以这不是资源有限的微控制器,而可能是嵌入式 linux 或其他操作系统。从系统工程的角度来看,嵌入式系统究竟需要什么以及以什么形式存在?再上一层,你有什么资源,因此你想用什么形式把数据保存在嵌入式系统上,嵌入式系统是否想要简单地采用预先格式化的二进制文件并将字节直接传递给数据用于的任何外围设备?在这种情况下,嵌入式驱动程序可能非常愚蠢/简单/可靠,并且大部分工作和调试都在主机端,那里有大量资源和马力来格式化数据。我的目标是最小化格式和开销,如果你必须包含一个库来解析它,我可能不会使用它。但我经常使用没有操作系统的资源有限的嵌入式系统。

于 2010-08-02T14:07:06.050 回答
1

我正在做类似的事情,从 SD 卡读取数据到嵌入式处理器。我必须考虑转换卡上数据的紧凑性和易用性,以及我们的子公司和潜在客户读取数据的能力。

如果数据不是经常被人工读取,转换工具可能会给你最好的折衷方案,但如果你需要提供转换工具,那么这将是很多额外的支持(如果它在最新版本的Windows、Linux 等)。

对于我的情况,由于周围有大量易于使用的 csv 编辑器(如 excel),CSV 证明对我的应用程序是一个合理的折衷方案,并且只需要提供有关如何生成/编辑 csv 文件的文档。CSV 不是一个完全定义的标准是一种痛苦,但 RFC4180 是一个很好的 csv“标准”。

https://www.rfc-editor.org/rfc/rfc4180

正如另一个答案所说,我不能给你一个明确的答案,但正如你已经确定的那样,这将是每个人对系统的可维护性与嵌入式解决方案的速度和大小(即它工作!)之间的折衷。

祝你好运!

于 2010-08-02T14:05:47.180 回答
1

来自YAML 网站

JSON 和 YAML 都旨在成为人类可读的数据交换格式。但是,JSON 和 YAML 有不同的优先级。JSON 的首要设计目标是简单性和通用性。因此,J SON 的生成和解析是微不足道的,但代价是降低了人类的可读性。它还使用最低公分母信息模型,确保任何 JSON 数据都可以被每个现代编程环境轻松处理。

相比之下,YAML 的首要设计目标是人类可读性和对序列化任意本机数据结构的支持。因此,YAML 允许非常可读的文件,但生成和解析更复杂。此外,YAML 超越了最低公分母数据类型,在跨不同编程环境时需要更复杂的处理

所以 JSON 要好得多,因为它是人类可读的并且 YAML 更有效。

于 2010-08-04T06:32:51.417 回答
1

我最近设计了自己的用于与移动设备通信的序列化方案,只是为了让我的内部版本与 Google protobufs 的公开公告相吻合。这有点令人失望,因为 Google 的协议要好得多。我建议调查一下。

例如,看看简单的数字。解析 JSON、XML 或 CSV 都需要解析 ASCII 数字。ASCII 让你每字节大约 3.3 位;protobuf 为您提供 7. 解析 ASCII 需要查找分隔符并进行数学运算,protobuf 只需要进行位摆弄。

当然,protobuf 不能直接读取消息。但是可视化器很快就被破解了。Google 已经完成了艰苦的工作。

于 2010-08-04T07:15:33.457 回答