TCP数据包格式化的任何好建议?

时间:2009-03-22 20:44:20

标签: tcp

我正在创建一个手机应用程序,它通过TCP连接将加速度测量结果发送到服务器。

我想尽可能地减少消息长度,但同时我希望能够在不需要修改接收器解析机制的情况下扩展当前格式。

一开始我发送一个字符串,格式如下:

##measurementTime#AccelerationX#AccelerationY#AccelerationZ

实施后的butsoon我在消息中添加了一些其他数据,我意识到如果我不得不经常修改格式,将需要很长时间。

我在考虑XML,但它增加了很多负载,当然我想避免(测量每100-250毫秒发送一次)。

5 个答案:

答案 0 :(得分:4)

我想在InSciTek Jeff's answer上稍微建立一下。这通常被称为标签长度值编码。想法是第一个代码是标签,它告诉你如何解释这个值。第二个代码是 length ,它告诉你值中有多少字节。这是进行可扩展二进制编码的一种很好的方法,在MPEG编码中经常使用。

我会在一个好的功能二进制协议上添加一些提示/要求:

  1. 在每条消息中包含版本号,其中包含消息的协议版本
  2. network byte order
  3. 中的每个多字节字段进行编码
  4. 仔细考虑每个字段的大小
  5. 考虑对整数使用多字节编码方案:我找不到一个好的引用,但想法是如果有更多字节则顶部位为1,如果这是最后一个字节则为0,而低七位每个字节中的位包含值。
  6. 将所有内容打包到电线上作为字节,从不构造
  7. 第一个非常重要。更重要的是,您计划变更并仔细决定协议将如何变化。如果消息不支持版本号,客户端绝不应尝试解释消息。 NEVER!

    在实现稳定实施时,第五个非常重要。我已经为嵌入式设备编写了很多二进制协议实现,并且使用压缩结构是我最后悔的错误。我有太多与忘记字节交换数字字段或不打包结构相关的缺陷。只需编写一个很好的字节打包和解压缩原语库,彻底测试它,并虔诚地使用它。

    如果您在设计和实施协议时考虑到这些原则,那么当您必须支持和扩展时,它将使您的生活变得更加轻松。我强烈建议的最后一件事是为你的协议编写Wireshark之类的解剖器。它还可以使部署,测试和支持更容易。只需确保完全理解编写此类解剖器的可能的法律含义,并在考虑之前部署解剖器。

答案 1 :(得分:2)

如果您需要完全坚持ASCII文本类型流,建议您发送简单的密钥名称/值对。密钥名称用于描述每个值传达的字段名称,类似于原始提案:

##keyName1=value1#keyName2=value2#

或者,您可以使用二进制标记格式发送数据,例如:

<tagCodeNum><lengthInBytes><tagValueAsBytes>

其中tagCodeNum可能是一个字节或字,长度是一个字节或字,具体取决于您的需要。这种格式的想法是接收器可以通过代码编号识别它理解的字段,然后还可以跳过它不知道如何解码的标签。以这种方式,编码变得可扩展。如果您需要将多个标签分组为逻辑消息,我会将一组这些二进制编码标签包装在整个消息层次结构中:

<messageCodeNum><lengthInBytes><tag><tag><tag>

上面的标记是上述前一个标记结构的复制,length表示所有标记组合在一起的字节长度。

注意:如果你考虑这个结构,与XML类型结构不同,但它更加简洁和受约束,因此解码几乎是微不足道的。

答案 2 :(得分:1)

如果您想减小尺寸,我真诚地建议您将数据包结构更改为二进制格式,这也将允许轻松扩展,具体取决于您如何划分数据包。

您可以执行以下操作:

  

n字节开头+大小
  n字节时间
  2-8字节x
  2-8字节y
  2-8字节z

答案 3 :(得分:0)

考虑优化的事情:
- 仅发送与先前值的差异;
- 不时发送完整的框架;
- 不要使用xml,进行结构定义;

答案 4 :(得分:0)

  

我在考虑XML,但它增加了很多负载

您可以改用JSON。它不像二进制格式那样紧凑,但比XML更紧凑。您可以轻松扩展数据格式。