二进制数据包解析

时间:2014-12-23 15:02:01

标签: sockets parsing networking protocols packet

我正在通过网络远程操作远程站点机器人。

我从头开始,我正在考虑将命令包发送给机器人。

我想使用简单的协议。

  

[LENGTH] [HEADER] [BODY]

     

LENGTH是[HEADER + BODY]的字节。

     

HEADER将包括命令类型,当前模式等......

     

BODY将包括真实数据(目标位置,速度,扭矩等......)

我的问题是这个。

如果我使用此协议,首先我获取数据包的长度,并根据长度信息从流中提取数据。

但让我们考虑“长度数据错误”的情况。

  

数据包流...

     

[10] [5Bytes] [10Bytes] | [15] [5Bytes] [10Bytes] | [15] [5Bytes] [10Bytes] ......

第一个数据包中存在长度错误。

我认为此错误可能会破坏其后的每个数据包。

我将UDP用于命令包,并不保证数据将被正确接收。

我认为这种情况是可能的。

真的发生了吗?

如果是,有什么解决办法吗?

4 个答案:

答案 0 :(得分:1)

如果数据丢失,尤其是如果需要字节丢失,则需要将协议设计为自我同步

在一般情况下,您需要明确规定。

在您的情况下,您可以通过仔细观察您的数据来规避此规定。

依靠UDP

如果您的数据足够小(在每个wiki的65,507 bytes下),您可以选择将每个命令作为单个UDP数据报发送。

您也可以选择将多个命令分组到UDP数据报中,但总是要使单个命令不能跨越UDP数据包。

然后使用套接字API中的sendtorecvfrom函数来发送和接收具有所选边界的数据报。

依靠数据本身

  • 数据报= [1-byte-len] [header] [data]
  • 假设空标头无效
  • 长度字节必须为[1..255]
  • 假设流中经常有数据帧[4] [4字节标题] [无数据]
  • 或者编译最频繁的数据报长度列表(5,10,13,200)
  • 验证数据以检测何时不同步

恢复方案可能是这样的:

  • 处理[5] [header-set-speed] [255,173,14,0]
  • 哦不,速度255没有意义
  • 假设同步丢失
  • 向前扫描寻找可能的起始字节(例如4)
  • 发现4,100,23,34,56,4,78,...假设它是一个数据报(4,100,23,34)
  • 在此之后检查数据报(4,78,...)
  • 此下一个数据报签出,确定同步已恢复

答案 1 :(得分:0)

如果要使数据交换或多或少可靠,则需要为包和验证器实现模式。但最简单的方法是使用现有的数据格式之一,如json,xml,bson等。

答案 2 :(得分:0)

所以从我看到你将所有传入的数据存储在连续缓冲区中,当长度属性被破坏时问题就是丢失了分割点。

现在,如果你正在处理传统套接字,你不应该担心拥有可靠数据流的数据链责任是什么。套接字以块的形式返回可靠的数据,如果需要,您可以自由地将其添加到缓冲区。

但是,让我们为每个数据包使用 256字节的小块

作为使用套接字接收数据的示例,您将执行以下操作:

unsigned char* data = new unsigned char[256];

int size = recvfrom(sock, data, sizeof(buffer), ...);

这将使datasize填充新数据包的内容。您现在可以使用if(size > 0)检查数据缓冲区中是否有任何数据,并从data缓冲区获取数据包数据。

我还建议使用 TCP 发送需要可靠性的简单命令。除非您连续发送具有最新状态的命令。编写自己的 UDP 可靠性系统非常棒,并且可以灵活地发送可靠或不可靠的命令,但它非常复杂,因此存在ENet等库。

答案 3 :(得分:0)

  

第一个数据包中存在长度错误。

除非您已禁用UDP校验和,否则无法使用UDP。

  

我认为此错误可能会破坏其后的每个数据包。

如果发生,则为真,但不能。

  

我会使用UDP作为命令包,但它并不能保证正确接收数据。

是的,除非您已禁用UDP校验和。

  

我认为这种情况是可能的。

没有

  

真的发生了吗?

没有

  

如果是,有什么解决办法吗?

你不需要。