AMF協(xié)議的數(shù)據(jù)封裝和文件解析
在前面我們已經(jīng)對AMF協(xié)議的相關(guān)內(nèi)容進行了講解。不知道大家是否已經(jīng)掌握了,而且我們也強調(diào)了兩個版本的不同和差異?,F(xiàn)在我們將繼續(xù)闡述有關(guān)的知識。希望大家能從中得到幫助。那么接下來就要將一個完整的AMF協(xié)議文件的封裝格式了。AMF文件總體來說分為4部分:前言(Preamble)、AMF頭、AMF主體和主體的響應(yīng)。前言的前2字節(jié)用于說明AMF的版本,目前AMF有2個版本AMF0和AMF3.如使用AMF0則是:00 00。第3和第4字節(jié)用16位整數(shù)表示AMF頭的數(shù)量。每一個AMF頭是由以下四部分組成:
◆UTF string 表示Header的名字
◆Boolean 表示該Header是否是必須的
◆Int32表示Header的長度,但是好像很多情況下該值為FF FF FF FF,似乎這個字段沒有意義。
◆Variable變量是某種AMF協(xié)議數(shù)據(jù)類型。
在Header表示完后,接下來是一個16位的整數(shù)用來表示AMF主體的數(shù)量,在這個數(shù)量之后才是AMF主體。
AMF主體主要由以下四部分組成:
◆UTF String - Response表示請求的類和方法或響應(yīng)的結(jié)果。
◆UTF String - Target是一個標識,其作用就是為了實現(xiàn)請求和響應(yīng)的對應(yīng),通過Target找到該響應(yīng)對應(yīng)的請求。一般使用自增整數(shù)。
◆Int32- 表示主體的長度,該字段一般沒有什么用
◆Variable變量表示主體的數(shù)據(jù)。
主體響應(yīng)是客戶端向服務(wù)器發(fā)送一個AMF請求以后服務(wù)器做出的和請求的主體格式相同的AMF響應(yīng),但是主體響應(yīng)中的內(nèi)容有所不同:
◆Response: 被設(shè)置為字符串‘null'.
◆Target: 是請求的Target值再加上“/onStatus", “onResult", 或者 “/onDebugEvents"組成. “/onStatus" 是為運行時錯誤而準備的我們一般不關(guān)心這個. “/onResult" 表示該請求被正確調(diào)用. “/onDebugEvents" 是在調(diào)試時使用的,這里也不用關(guān)心. 如果請求的Target是‘/1', 那么被成功調(diào)用以后的主體響應(yīng)應(yīng)該是: ‘/1/onResult' 。
◆Data:就是響應(yīng)后返回的AMF協(xié)議文件對象。
說了這么多估計還是感覺比較抽象,下面給出個實例:#p#
AMF協(xié)議16進制內(nèi)容
00000000h: 00 00 00 00 00 01 00 1B 7A 68 2E 66 6C 65 65 74 ; ........zh.fleet
00000010h: 53 65 72 76 69 63 65 2E 67 65 74 46 6C 65 65 74 ; Service.getFleet
00000020h: 52 6F 77 00 03 2F 37 39 00 00 00 13 0A 00 00 00 ; Row../79........
00000030h: 03 02 00 01 35 02 00 03 38 34 35 02 00 01 35; ....5...845...5
以上是客戶端向服務(wù)器發(fā)送的一個AMF請求。我們可以按照前面說的封裝方式將該amf解析如下:
00 00(AMF0版本)00 00(Header個數(shù)為0)00 01(AMF主體有1個)
00 1B(請求的方法的字符串長度為27個字節(jié))
7A ……77(這27個直接就是調(diào)用的類和方法:“zh.fleetService.getFleetRow")
00 03(請求的Target字符串長3字節(jié)) 2F 37 39(Target的內(nèi)容:“/79")
00 00 00 13(主體的長度為19)
0A(傳入的變量是一個Array)00 00 00 03(該Array的長度為3)02 00 01 3***rray的***個值是字符串“5")02 00 03 38 34 3***rray的第二個值是字符串“845")02 00 01 3***rray的第三個值是字符串“5")
現(xiàn)在整個AMF協(xié)議對象都解析出來了,我們可以認為是客戶端調(diào)用了服務(wù)器的方法:zh.fleetService.getFleetRow("5", "845", "5")
服務(wù)器返回的AMF文件的內(nèi)容的解析方式相同,這里我就不再重復(fù)了。
現(xiàn)在我們已經(jīng)對AMF文件有了一個清晰的認識了。那么接下來就是要抓包,看某些在Flex上的操作對應(yīng)的發(fā)送了什么AMF文件,服務(wù)器返回了什么AMF文件。將這些AMF協(xié)議文件解析出來然后就可以看到調(diào)用了API了。