Clientsql |
|
|
|
Server數組 |
1session |
-------app |
Data Piggyback(11) Cursor Close All(69)spa 注意此處也有多是 116b,035e,0303.net |
----->指針 |
具體語句orm |
2blog |
<-----ci |
Data DescribeInfo(10) 17 |
------- |
返回列 |
3 |
------- |
Data UOCIFun(03) FetchARow(05) |
-----> |
獲取其餘值 |
4 |
<----- |
Data RowTransferHeader(06) 01 |
------- |
返回值 |
11g,12c有三種sql命令執行的模式:
參考網上其餘文章Oracle 9.2還有可能使用0303來發命令,而對其的返回(上述流程中2處)可能使用data 1019的包
|
32bit |
64bit |
|
序列號 |
1 |
1 |
|
Piggyback cusor close all (1169) command |
9 or 13 |
16 or 20 |
|
Buddle execute (035e)command |
變長 |
變長 |
|
參考網上一些文章,Oracle9,10 Piggy Command長度爲12
這個部分是變長的,下面是幾種變化,都以feMagic(定義參見本系列第二篇 《Oracle TNS 314 協議分析---基礎包結構》)數組開頭,有的長16個字節,有的20個字節
語句 |
Plsql |
Sqlplus |
Navicat |
Select |
fe ff ff ff ff ff ff ff 01 00 00 00 04 00 00 00 |
fe ff ff ff ff ff ff ff 01 00 00 00 00 00 00 00 05 00 00 00 當沒有輸入;05會變03 |
fe ff ff ff ff ff ff ff 01 00 00 00 05 00 00 00 |
Update |
fe ff ff ff ff ff ff ff 01 00 00 00 02 00 00 00 |
fe ff ff ff ff ff ff ff 01 00 00 00 00 00 00 00 06 00 00 00 |
|
Delete |
fe ff ff ff ff ff ff ff 01 00 00 00 02 00 00 00 |
fe ff ff ff ff ff ff ff 01 00 00 00 00 00 00 00 03 00 00 00 |
|
Insert |
|
fe ff ff ff ff ff ff ff 01 00 00 00 00 00 00 00 05 00 00 00 有時是0b 有時是09 |
|
CreateTable |
|
fe ff ff ff ff ff ff ff 01 00 00 00 00 00 00 00 07 00 00 00 |
|
|
32bit |
64bit |
|
序列號 |
1 |
1 |
|
Piggy command |
12 |
12 |
|
Buddle execute command 035e |
變長 |
變長 |
|
Oracle9 10 Piggy Command長度也爲12
|
32bit |
64bit |
ThinClient |
|
序列號 |
1 |
1 |
1 |
|
命令相關 |
8 |
8 |
5 |
|
feMagic |
1 |
8 |
1 |
|
語句長度相關字段 |
2 |
2 |
1 |
|
未知 | 2 | 2 | 1 | |
固定字節 |
54 |
152 |
41 | 全部命令都相同 |
SQL命令 |
變長 |
變長 |
變長 |
|
尾部字節 |
52 |
52 |
17 | 01開頭 |
根據其餘文章來看Oracle九、10(TNS312,313)下這個包有必定區別(主要是從序列號到SQL的字節數分別爲80,92,而11,12爲172)下面是根據其餘文章分析的包結構
序列號 |
1 |
|
固定長度頭部 |
80 or 92 |
|
SQL命令 |
變長 |
SQL查詢語句 |
尾部字節 |
48 |
|
ThinClient發出的包與此相差較大,將另文描述
各個平臺各類語句調用以下
語句 |
PlSQL |
SQLplus |
Navicat |
Thin Client |
Select |
61 80 00 00 00 00 00 00 |
61 80 00 00 00 00 00 00 |
61 81 00 00 00 00 00 00 |
02 80 21 00 01 |
Update |
21 80 00 00 00 00 00 00 |
21 80 00 00 00 00 00 00 |
21 81 00 00 00 00 00 00 |
|
Delete |
21 80 00 00 00 00 00 00 |
21 80 00 00 00 00 00 00 |
21 81 00 00 00 00 00 00 |
|
Insert |
21 80 00 00 00 00 00 00 |
21 80 00 00 00 00 00 00 |
21 81 00 00 00 00 00 00 |
|
CreateTable |
21 80 00 00 00 00 00 00 |
21 80 00 00 00 00 00 00 |
21 81 00 00 00 00 00 00 |
|
AlterTable |
21 80 00 00 00 00 00 00 |
21 80 00 00 00 00 00 00 |
21 81 00 00 00 00 00 00 |
紅色部分見過這些取值
61 80 plsql select
61 81 navicat select
01 80 02 plsql select another
29 04 04 plsql declare function
29 05 04 navicat declare function
21 80 plsql 除select 外
21 81 navicat 除select 外
21 01 04 navicat call function
而在ThinClient中,返現Endian會發生變化,且前序一個長度字節的狀況,且此字段長度也不相同
因而21 80會變成 02 80 21
此字節與sql長度有關,OCI Client 下爲sql長度字段大小*3,若是sql較長,則會產生進位,注意進位後是little endian的形式,02 01 表示102,ThinClient下直接就是語句長度,ThinClient下語句前不會再附加長度,此處是獲取長度的最佳地點。
39 00 00 00 表示 0x39
21 01 00 00 表示 0x121
在命令超長的狀況下,這個長度字段很是有用,由於一個command會在多個TNSData包中出現,必須用這個長度字段和TNS Command Header的長度字段,才能正確組合超長命令。
上圖中能夠看出,一個超長命令可能跨越多個TNS包,若是一個TNS包中的Command長度不足,說明尚未收取完畢,須要繼續從buffer中讀取數據,直到命令長度知足要求。另外處理程序若是工做在應用層,那麼處理程序從buffer中取出的數據可能橫跨多個TNS包,因爲每一個TNS包都有本身的頭部,就會在解析的命令中引入這些額外的頭部。爲了跳過這些頭部,必須利用第一個TNS 的package Length做爲指針,逐個找到每一個頭部,從而處理這些額外的10字節頭。
後續19*8=152個固定字節,使用navicat和plsql不管什麼命令都相同:
0000 fe ff ff ff ff ff ff ff 0d 00 00 00 fe ff ff ff ........ ........
0010 ff ff ff ff fe ff ff ff ff ff ff ff 00 00 00 00 ........ ........
0020 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
0030 00 00 00 00 00 00 00 00 00 00 00 00 fe ff ff ff ........ ........
0040 ff ff ff ff 00 00 00 00 00 00 00 00 fe ff ff ff ........ ........
0050 ff ff ff ff fe ff ff ff ff ff ff ff fe ff ff ff ........ ........
0060 ff ff ff ff 00 00 00 00 00 00 00 00 fe ff ff ff ........ ........
0070 ff ff ff ff fe ff ff ff ff ff ff ff 00 00 00 00 ........ ........
0080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
0090 00 00 00 00 00 00 00 00 ........
後續54個固定字節
0000 01 0d 00 00 00 01 01 00 00 00 00 01 00 00 00 00 ........ ........
0010 00 00 00 00 00 00 00 00 00 01 00 01 01 01 00 00 ........ ........
0020 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 00 ........ ........
0030 00 00 00 00 00 00
後續41個固定字節
0000 01 0d 00 00 04 ff ff ff ff 01 0a 04 7f ff ff ff ........ ........
0010 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ........ ........
0020 00 00 00 00 00 00 00 00 00
後續馬上接sql,sql遵循變長字符串或數組形式,即len+值定義,第一個字節爲長度,或fe表示數組,數組中元素也是變長字符串,當爲數組時數組由00結尾,全部sql都後續01。若是輸入時忘記輸入;語句後會多個0a,因此結尾看起來是0a01或0a0001(變長)。
00A0 13 53 45 ........ ......SE
00B0 4c 45 43 54 20 2a 20 46 52 4f 4d 20 44 45 50 54 LECT * F ROM DEPT
00C0 0a 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
00D0 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 ........ ........
00E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
00F0 00 00 00 00 00
ThinClient下發現此包無前序長度,長度由前面長度相關字段肯定
根據其餘文章在Oracle9.2下有可能使用這種包發送命令(本文11,12 64bit下未測得),其格式以下
Request id |
1 |
|
Magic |
12 |
|
Data Format |
可變 |
查詢語句 |