Flash发送的未知数据包

unknown packets sent by Flash

我正在使用我在互联网上找到的项目学习 Flash (AMF) 和 Java (BlazeDS),但我注意到服务器正在通过套接字接收以下数据:

当我尝试使用 Amf0Input/Amf3Input me 到 return 对象时,我收到无法识别此类包的错误。有人知道我应该使用哪个库来解码这条消息吗?

你得到的数据包似乎是一个长度为前缀的 AMF3 AmfObject。

一般来说,每当您看到一个字符串遵循完全限定 class 名称(即像反向域)的通常命名约定时,您很可能正在处理一个 object 实例1.

查看前几个字节,您会看到 0x00 重复了三遍。如果我们假设 AMF3, this would be 3 undefineds, followed by an object with type marker 0x3e - which does not exist. If we instead assume AMF0,我们将首先有一个数字(0x00 类型标记,后跟 8 个字节的数据),然后是一个具有类型标记 0x6d 的对象——同样不存在.

因此,您获得的数据不可能只是 AMF 负载。但是,如果我们将前 4 个字节解释为网络字节顺序(即大端)整数,我们会得到 0x3E = 62 - 这正是剩余数据的长度。

然后假设前 4 个字节只是长度前缀,下一个字节必须是类型标记。在 AMF3 中,0x0a 表示一个 object 实例。所以让我们试着解码剩余的数据(AMF3 spec 的第 3.12 节,如果你想跟进2):下一个字节必须指示对象特征。 0x23 意味着我们对该字节中的特征进行了直接编码——而不是对先前提交的特征的引用。

由于第四位(从最低位开始计算)为 0,因此该对象不是动态的 - 就像某些 class 的实例,而不仅仅是普通对象实例。剩下的位,右移4位,表示该实例拥有的密封属性个数,即2。

接下来,我们期待 class 名称,编码为 UTF-8-vr - 即长度前缀(当右移 1 时),UTF-8 编码字符串。下一个字节是0x1d,也就是说长度是0x1d >> 1 = 14。接下来的 14 个字节编码 common.net.APC,因此这是实例的 class 名称。

之后,我们有两个密封的属性名字,也被编码为UTF-8-vr。第一个前缀为 0x15,因此长度为 10 - 给我们 parameters,后跟前缀 0x19(长度 12)和有效负载 functionName

在此之后,您将获得与这些密封属性对应的值,顺序相同。第一个有一个 0x09 的类型标记,它对应于一个数组。长度标记是0x03,这意味着数组包含一个元素,下一个字节是0x01,表明我们没有关联成员。唯一的元素本身有一个类型标记 0x04,这意味着它是一个 integer - 在这种情况下值为 0.

后面跟着 0x06 的类型标记 - 一个长度为 14 的字符串。您现在可能已经猜到该字符串是 syncServerTime.

因此,总而言之,您的数据包是 common.net.APC 的长度前缀实例,其 parameters 属性设置为 [0]functionName 属性设置至 "syncServerTime".


1:唯一的其他选择是对象实例的向量——这将需要某处的类型标记 0x10——或 AMF0 数据包。在 AMF0 数据包的情况下,您还必须在数据包中的某处具有 URI 样式的路径,而此处不是这种情况。

2:请注意,本节末尾给出的 EBNF 并不完全正确——无论是在句法上还是在语义上...