1. 程式人生 > >mysql協議分析1---報文的格式和基本型別

mysql協議分析1---報文的格式和基本型別

navicat 和 mysql 是一對好基友,每天都有非常頻繁的交流,主人在navicat上寫下每條sql語句,輕輕的點了下執行按鈕,navicat就飛快的把主人的指令傳送到mysql那裡,mysql立馬把返回結果傳回navicat那裡顯示給主人看。主人對他們的效率很滿意,同時主人也有點好奇:你們兩個基友是怎麼通訊的呢?如果不通過navicat,我用程式直接和mysql互動該怎麼做呢?

mysql 笑道:這是我們之間的祕密。。。

navicat有點不開心了:難道主人想拋棄我嗎?嗚嗚嗚。。。

主人安慰道:你想多了,我只是想更瞭解你們呀。

 

那我就給你詳細講講我們之間的小祕密吧,mysql悠悠的說道:

想要通過我的互動,就得照我規定的格式來,不能每個人過來都講自己的方言,我可聽不懂,來到我的地盤就得按我的規矩來。

1.我給你發的報文都是這種格式的:

  伺服器--->客戶端的報文格式

  

   前面3個位元組payload_length表示後面資料的實際長度,中間一個位元組sequence_id表示報文的序號,從0開始,每次加1,最後的paylaod就是我發你的內容啦。

   你可能也發現了,payload_length用3個位元組表示,最大隻能表示 224−1 bytes也是16M,如果報文大於或者等於16M那就要拆成2個報文了哦,

   比如剛好傳送16M的報文:

ff ff ff 00 (資料域16M)...
00 00 00 01 (資料域為空)

   第二個報文的資料域是空的。

 

2.客戶端發給我的報文也是要按照一定格式的哦:

客戶端--->伺服器的報文格式

   第一個位元組表示命令的型別

 

  

 

 後面的位元組表示具體的命令,例如關閉連線的報文是長這樣子滴:

  

 這樣規定好後,我們就有共同語言啦,就能聽得懂對方在講什麼了,所以說有共同語言是很重要滴。

 

  主人細細的回味了下mysql剛才說的話,發現還有個地方沒弄明白問道:你發給我的報文中int<3>,string<var>表示什麼意思呀?

  mysql忽然意識到還忘了說一件重要的事情:哎呦,我忘了和你說基本的資料型別了。

 mysql有2種基本的資料型別:

 Integers(整數型)String(字串)

 

  Integers(整數型)分為定長的整數型別(Fixed-length integers)和變長的整數型別(Length-encoded integers)

   1.定長的整數型別(Fixed-length integers)分別能表示1,2,3,4,6,8位元組的長度:

    

    int<1>表示佔1個位元組的長度, int<2>表示佔2個位元組的長度,以此類推,

   比如 int<3> 表示1是這麼表示的:01 00 00   

   對了,mysql協議中位元組是按小頭(LittileEndian)的方式表示的,低位的位元組在前面,總體佔3個位元組,所以第一個位元組是01,後面是00 00

 

  2.變長的整數型別(Length-encoded integers)

 

  • 如果數字 < 251, 就用一個位元組表示 = 1個位元組 
  • 如果數字 ≥ 251 並且 < (216),就用 fc + 2個位元組表示  = 3個位元組 
  • 如果數字 ≥ (216) 並且 < (224),就用 fd + 3個位元組表示  = 4個位元組
  • 如果數字 ≥ (224) 並且 < (264) ,就用 fe + 8個位元組表示  = 9個位元組

   

   主人表示很奇怪:一個位元組最多能表示255個數,為什麼不能直接表示到255?而是隻表示到250?

   mysql微微一笑道:因為251,252,253,254,255已經被我徵用了哦,它們表示特殊的用途:

   251(fb):表示 NULL

   252(fc):表示數值的大小佔後面的2個位元組

   253(fd):表示數值的大小佔後面的3個位元組

   254(fe):表示數值的大小佔後面的8個位元組

   255(ff): 表示一個錯誤報文 ERR packet



下面說說String(字串)型別:

1.變長的字元型別(LengthEncodedString):和上面變長整數型別是一樣的,根據第一個位元組的值判斷所佔位元組的長度

2.
定長的字串型別(FixedLengthString):後面的數字表示字串所佔位元組的長度

3.動態的計算長度(VariableLengthString):
根據var動態的計算長度
4.包末端字串方式(RestOfPacketString):沒搞懂
5.空結尾的字串型別(NulTerminatedString):字串遇到 00 結束
 
原來如此,主人豁然開朗,看著navicat 和 mysql都親切了許多,知道他們之間是怎麼通話之後,一個邪惡的想法慢慢從心底升起,嘿嘿,那我不就可以監聽他們之間的對話了嘛,哈哈哈哈哈哈哈哈。。。


我的公眾號,歡迎關注