java - Flash发送的未知数据包

标签 java sockets flash blazeds amf

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

enter image description here 当我尝试使用 Amf0Input/Amf3Input 返回对象时,出现无法识别此类包的错误。有人知道我应该使用哪个库来解码此消息吗?

最佳答案

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

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

查看前几个字节,您会看到 0x00 重复了三次。如果我们假设 AMF3 ,这将是 3 个 未定义,后跟一个带有类型标记 0x3e 的对象 - 该对象不存在。如果我们假设 AMF0 ,我们首先有一个数字(0x00 类型标记,后跟 8 个字节的数据),然后是一个具有类型标记 0x6d 的对象 - 它又不存在。

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

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

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

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

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

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

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

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

<小时/>

1:唯一的其他替代方案是对象实例 vector - 这需要在某处使用 0x10 类型标记 - 或 AMF0 数据包。对于 AMF0 数据包,您还必须在数据包中的某个位置有一个 URI 样式的路径,但此处的情况并非如此。

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

关于java - Flash发送的未知数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37420693/

相关文章:

iphone - Haxe - Flash 项目编译良好,但无法使用 hxcpp 进行编译

flash - 使用 URLStream 暂停/恢复下载?

java - 每次我尝试打开 eclipse 时都无法创建 java 虚拟机错误

java - 使用静态实例化方法在构建器类中 Autowiring 依赖项

java - 如何将对象实例的类型与泛型进行比较?

java - 电话键盘格式的字母到数字转换器

c# - WCF 与套接字性能

python - 如何在 Python 中将 INET 套接字连接到 PTY 设备

php - 如何通过套接字在 PHP 和 C++ 应用程序之间进行通信?

javascript - 使用 flash/AS3 读取第一方 cookie