2016-05-24 63 views
0

我正在学习有关Flash(AMF)和Java(BlazeDS的)使用我发现在互联网上的项目,但我注意到,服务器通过套接字接收下面的数据发送的数据包不明 当我尝试使用Amf0Input/Amf3Input来返回对象时,出现无法识别此类包的错误。任何人都知道我应该使用哪个库来解码此消息?由Flash

回答

3

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

一般情况下,当你看到下面的全类名的通常命名约定(即像反向域)的字符串,没准你正在处理一个object实例。

看前面的几个字节,你会看到0x00重复三次。如果我们假设AMF3,这将是3 undefined s,后面跟着一个类型标记为0x3e的对象 - 它不存在。如果我们假设AMF0,我们首先会有一个数字(0x00类型标记,后面是8个字节的数据),后面跟着一个类型标记为0x6d的对象 - 这个对象再次不存在。

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

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

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

接下来,我们期望类名,编码为UTF-8-vr - 即长度前缀(当向右偏移1时) ,UTF-8编码的字符串。下一个字节是0x1d,表示长度为0x1d >> 1 = 14。接下来的14个字节编码​​,所以这就是实例的类名。

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

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

然后是一个类型标记0x06 - 一个字符串,长度为14.该字符串 - 您现在可能已经猜到了 - 是syncServerTime

因此,简言之,你的包是​​长度为前缀的情况下,与它的parameters属性设置为[0],和functionName属性设置为"syncServerTime"


1:唯一的其他选择是对象实例的矢量 - 这将需要的0x10一个类型标记某处 - 或AMF0分组。在AMF0数据包的情况下,你还必须在数据包的某个地方有一个URI风格的路径,这里就不是这种情况。

2:请注意,在本节的最后给出的EBNF并不完全正确的 - 既不是句法语义也不...

+0

谢谢,它解决了我的问题 – ExtremsX