Netty(四)分隔字元與定長解碼器的使用,netty分隔字元解碼器
TCP以流的形式進行資料轉送,上層的應用協議為了對訊息進行劃分,往往採用如下的4種方式。
(1)訊息長度固定,累計讀到長度總和為定長len的報文後,就認為讀取到了一個完整的訊息;然後重新開始讀取下一個“完整”的資料包;
(2)將斷行符號分行符號作為訊息結束符,如ftp協議;
(3)將特殊的分隔字元作為訊息的結束標識,斷行符號分行符號j是一種特殊的分隔字元;
(4)通過在訊息頭中定義的長度欄位表示訊息的總長度;
Netty對以上4種應用做了抽象,提供了4種解碼器,有瞭解碼器,碼農們不用考慮TCP的粘包、拆包的問題了。
LineBasedFrameDecoder:依次編譯bytebuf中的可讀字元,判斷看是否有“\n”或者“\r\n”,如果有,就以此位置為結束位置,從可讀索引到結束位置區間的位元組就組成了一行。它是以分行符號為結束標誌的解碼器,支援攜帶結束符或者不攜帶結束符兩種解碼方式,同時支援單行的最大長度。如果連續讀取到最大長度後,仍然沒有發現分行符號,就會拋出異常,同時忽略掉之前讀到的異常碼流。(具體例子介紹在《Netty(三)TCP粘包拆包處理》)
FixedLengthFrameDecoder:是固定長度解碼器,它能按照指定的長度對訊息進行自動解碼,開發人員不需要考慮TCP的粘包等問題。利用FixedLengthFrameDecoder解碼,無論一次性接收到多少的資料,他都會按照建構函式中設定的長度進行解碼;如果是半包訊息,FixedLengthFrameDecoder會緩衝半包訊息並等待下一個包,到達後進行拼包,直到讀取完整的包。
DelimiterBasedFrameDecoder:是自訂的分隔字元解碼,建構函式的第一個參數表示單個訊息的最大長度,當達到該長度後仍然沒有查到分隔字元,就拋出TooLongFrameException異常,防止由於異常碼流缺失分隔字元導致的記憶體溢出。
源碼下載
源碼在src/main/java/Decoder下,分為用戶端和服務端,他們的代碼基本和Netty入門章節的代碼類似,只是增加瞭解碼器。
GitHub地址:https://github.com/orange1438/Netty_Course