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

在此处输入图片说明 当我尝试使用Amf0Input / Amf3Input返回对象时,出现错误,无法识别这种类型的程序包。 有人知道我应该使用哪个库来解码此消息吗?

===============>>#1 票数:3 已采纳

您收到的数据包的长度似乎是AMF3 AmfObject的前缀。

通常,每当您看到一个遵循完全合格的类名的常规命名约定(即,像反向域)的字符串时,您就有可能在处理object实例1

查看前几个字节,您会看到0x00重复了3次。 如果我们假设AMF30x3e 3 undefined s,后跟一个标记类型为0x3e的对象-该对象不存在。 如果我们改为假设AMF0 ,那么我们将首先有一个数字( 0x00类型标记,后跟8个字节的数据),然后是一个对象,其类型标记为0x6d再次不存在。

因此,您获得的数据不能仅包含AMF有效负载。 但是,如果我们将前4个字节解释为网络字节顺序(即大端字节序)整数,则会得到0x3E = 62恰好是剩余数据的长度。

假设前4个字节只是长度前缀,则下一个字节必须是类型标记。 在AMF3中, 0x0a表示object实例。 因此,让我们尝试解码其余数据(如果要遵循2 ,则是AMF3规范的 3.12节):下一个字节必须指示对象特征。 0x23表示我们在该字节中具有特征的直接编码,这与对较早提交的特征的引用相反。

由于第四位(从最低有效位开始算起)为0,因此该对象不是动态对象-例如某个类的实例,而不仅仅是普通对象实例。 剩余的位向右移动4,表示此实例具有的密封属性的数量为2。

接下来,我们希望类名称以UTF-8-vr编码-即长度前缀(当右移1时),是UTF-8编码的字符串。 下一个字节是0x1d ,这意味着长度是0x1d >> 1 = 14 接下来的14个字节编码common.net.APC ,这就是实例的类名。

之后,我们得到了两个密封的属性名称,也被编码为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并不完全正确-语法或语义上都没有...

  ask by ExtremsX translate from so

未解决问题?本站智能推荐: