未知的AMF类型&将文件从Flash传输到java时的其他错误

时间:2011-11-03 15:04:08

标签: java actionscript-3 blazeds amf

我正在使用Flash工具将数据传输到Java。我遇到了一次发送多个对象的问题。发送的对象只是通用的Object对象,因此不需要注册类别名或任何东西。

发送一个对象可以正常工作。一旦我开始发送多个对象(将相同的对象放入数组并发送它),它就开始变得怪异了。数组中最多三个对象似乎工作正常。不仅如此,我在readObject()函数中得到了不同的错误,例如:

  • 未知AMF类型'47'
  • 未知AMF类型'40'
  • 未知AMF类型'20'
  • OutOfBoundsExceptions index 23,size 0
  • 的NullPointerException

发送3个对象将起作用,发送4会给我错误。如果我删除之前工作的3个之一(同时保留第四个已添加的),它将再次起作用。有谁知道发生了什么事?

更多信息:

  • 通信在Flash端通过Socket类。这是纯粹的AS3,没有flex。
  • 消息在服务器上发送和解压缩之前会被压缩,所以我很确定它不是缓冲区大小问题(除非我遗漏了什么)
  • BlazeDS版本似乎是jar上的4.0.0.14931
  • Flash版本为10.1(这是一个AIR应用程序)

使用粗略代码进行更新

正在发送的对象示例:

var o:Object    = { };
o._key          = this._key.toString();
o.someParam     = someString;
o.someParam2    = someInt;
o.someParam3    = [someString1, someString2, someString3];
...

它被添加到我们的事件对象(我们用它来确定要调用的事件,要传递的数据等)。事件对象已注册为类别名

该对象通过Socket发送到服务器,如下所示:

myByteArray.writeObject( eventObj );
myByteArray.compress();
mySocket.writeBytes( myByteArray );
mySocket.flush();

在服务器端,我们收到字节,并解压缩它们。我们创建一个Amf3Input对象并设置输入流,然后读取它:

Amf3Input amf3Input = new Amf3Input( mySerializationContext );
amf3Input.setInputStream( new ByteArrayInputStream( buffer ) ); // buffer is a byte[]
MyEventObj eventObj = (MyEventObj)amf3Input.readObject(); // MyEventObj is the server version of the client event object

如果它会以“未知的AMF类型错误”崩溃,它会立即这样做,即当我们尝试读取对象时,而不是当它试图读取子对象时。

在单步读取代码时,似乎当我传递一个对象数组时,如果长度为< = 4,则它会读取正确的长度。如果长度大于该长度,则将其长度读为4。

2 个答案:

答案 0 :(得分:1)

如果您收到AMF反序列化错误,可能会出现几个可能导致问题的问题。以下是进行进一步诊断的几种技术:

  1. 使用网络流量嗅探器确保您发送的内容与您收到的内容相符。在Mac上,我将使用CocoaPacketAnalyzer,或者您可以尝试Charles,它实际上可以解码它注意到的AMF数据包。

  2. 将数据提供给其他AMF库,例如PyAMFRocketAMF,以查看BlazeDS是否存在问题,或者您是如何调用它的。您也可能会收到不同的错误消息,以便更好地了解失败的位置。

  3. 检查AMF数据包的格式。 AMF服务器调用有一些额外的包装,如果它不期望遇到包装,则会抛出反序列化器,反之亦然,对于纯序列化对象。服务器呼叫数据包总是从0x00开始,然后是AMF版本(0x000x03,或者在极少数情况下0x02)。

答案 1 :(得分:1)

好的,我发现了问题。基本上,消息在服务器上发送和解压缩之前被压缩。我没有看到的是消息被解压缩到的byte[]缓冲区总是1024长度,这对于小对象数组来说很好。然而,一旦传递它,它将覆盖缓冲区(我不太确定当你尝试写入比可用字节更多的字节时,Java中会发生什么 - 无论它是循环还是移位数据)。

当谈到读取amf对象时,首先它会读取一个int,并使用它来确定它尝试解码的对象类型。由于这个int是乱码(47,110,-10),它失败了。

开始预设消息长度的时间我认为:)

感谢您的帮助。