AMF協議的數據讀取代碼解析
AMF協議規定的數據在使用HTTP方式傳輸時,用于ActionScript中,為了使Flex和Server能夠完好地通信。但是也有不少人對這個不太了解,下面我們對這方面的數據內容進行一下解析。
AMF協議是Action Message Format協議的簡稱,AMF協議是Adobe公司自己的協議,主要用于數據交互和遠程過程調用,在功能上相當于WebService,但是AMF與WebService中的XML不同的是AMF是二進制數據,而XML是文本數據,AMF的傳輸效率比XML高。AMF使用HTTP方式傳輸,目前主要是用于ActionScript中,即實現Flex和Server之間的通信。
AMF目前有兩種版本,AMF0和AMF3,他們在數據類型的定義上有細微不同。關于AMF的官方文檔參見這里。
- TypeByte codeNotes
- Number0×00
- Boolean0×01
- String0×02
- Object0×03
- MovieClip0×04Not available in Remoting
- Null0×05
- Undefined0×06
- Reference0×07
- MixedArray0×08
- EndOfObject0×09See Object
- Array0x0a
- Date0x0b
- LongString0x0c
- Unsupported0x0d
- Recordset0x0e Remoting, server-to-client only
- XML0x0f
- TypedObject (Class instance)0×10
- AMF3 data0×11 Sent by Flash player 9+
#p#對應的枚舉就是
- public enum DataType
- {
- Number = 0,
- Boolean = 1,
- String = 2,
- UntypedObject = 3,
- MovieClip = 4,
- Null = 5,
- Undefined = 6,
- ReferencedObject = 7,
- MixedArray = 8,
- End = 9,
- Array = 10,//0x0A
- Date = 11,//0x0B
- LongString = 12,//0x0C
- TypeAsObject = 13,//0x0D
- Recordset = 14,//0x0E
- Xml = 15,//0x0F
- TypedObject = 16,//0x10
- AMF3data=17//0x11}
以上表列出了每種數據類型的表示方法,這樣看并不容易理解,下面我就主要講解一下常用的一些格式:
0.Number這里指的是double類型,數據用8字節表示,比如十六進制00 40 10 00 00 00 00 00 00就表示的是一個double數4.0,在C#中可以使用如下代碼讀取該數據:
- byte[] d=new byte[]{0,0,0,0,0,0,0x10,0x40};
- //這里的順序是和amf協議文件中的順序正好相反,不要忘記了double num=BitConverter.ToDouble(d,0);
1.Boolean對應的是.net中的bool類型,數據使用1字節表示,和C語言差不多,使用00表示false,使用01表示true。比如十六進制01 01就表示true。
2.String相當于.net中的string類型,String所占用的空間有1個類型標識字節和2個表示字符串UTF8長度的字節加上字符串UTF8格式的內容組成。比如十六進制03 00 08 73 68 61 6E 67 67 75 61表示的就是字符串,該字符串長8字節,字符串內容為73 68 61 6E 67 67 75 61,對應的就是“shanggua"。在C#中要讀取字符串則使用:#p#
- byte[] buffer=new byte[]{0x73,0x68,0x61,0x6E,0x67,0x67,0x75,0x61};//03 00 08 73 68 61 6E 67 67 75 61
- string str=System.Text.Encoding.UTF8.GetString(buffer);
3.Object在.net中對應的就是Hashtable,內容由UTF8字符串作為Key,其他AMF協議類型作為Value,該對象由3個字節:00 00 09來表示結束。C#中讀取該對象使用如下方法:
- private Hashtable ReadUntypedObject()
- { Hashtable hash = new Hashtable();
- string key = ReadShortString();
- for (byte type = ReadByte(); type != 9; type = ReadByte())
- {hash.Add(key, ReadData(type));
- key = ReadShortString(); }
- return hash;}
4.Null就是空對象,該對象只占用一個字節,那就是Null對象標識0x05。
5. Undefined 也是只占用一個字節0x06。
6.MixedArray相當于Hashtable,與3不同的是該對象定義了Hashtable的大小。讀取該對象的C#代碼是:
- private Hashtable ReadDictionary()
- { int size = ReadInt32();
- Hashtable hash = new Hashtable(size);
- string key = ReadShortString();
- for (byte type = ReadByte(); type != 9; type = ReadByte())
- {object value = ReadData(type);
- hash.Add(key, value);
- key = ReadShortString(); }
- return hash;}
#p#7.Array對應的就是.net中的ArrayList對象,該對象首先使用32位整數定義了ArralyList的長度,然后是密集的跟著ArrayList中的對象,讀取該對象使用如下函數:
- private ArrayList ReadArray()
- { int size = ReadInt32();
- ArrayList arr = new ArrayList(size);
- for (int i = 0; i < size; ++i)
- {arr.Add(ReadData(ReadByte())); }
- return arr;}
8.Date對應.net中的DateTime數據類型,Date在類型標識符0x0B后使用double來表示從1970/1/1到表示的時間所經過的毫秒數,然后再跟一個ushort的16位無符號整數表示時區。讀取Date類型的C#代碼為:
- private DateTime ReadDate()
- {double ms = ReadDouble();
- DateTime BaseDate = new DateTime(1970, 1, 1);
- DateTime date = BaseDate.AddMilliseconds(ms);
- ReadUInt16(); //get's the timezone
- return date; }
9.LongString對應的也是string類型,不過和2對應的String不同的是這里使用32位整數來表示字符串的UTF8長度,而String使用的是16位。
10.XML是使用類型標識符0x0F后直接跟LongString類型的字符串表示。


















