分散式之Netty介紹與實戰(四)--Netty編解碼程式設計實戰
目錄
分散式之Netty介紹與實戰(三)–Netty執行緒模型解析
分散式之Netty介紹與實戰(四)–Netty編解碼程式設計實戰
- 半包粘包問題示例與分析
- Netty半包粘包問題解決
- Netty編解碼器分析
半包粘包問題示例與分析
TCP/IP協議
面向“流”協議 MSS: Maxitum Segment Size
最大分段大小,表示TCP資料包每次能夠傳輸的最大資料分段 傳送方/接收方緩衝區 Nagle演算法(順序出現)
粘包/拆包解決思路
基本思路就是不斷從TCP緩衝區中讀取資料,每次讀取完都需要判斷是否是一個完整的資料包
若當前讀取的資料不足以拼接成一個完整的業務資料包,那就保留該資料,繼續從tcp緩衝區中讀取,直到得到一個完整的資料包
定長、分隔符、基於長度變長包
若當前讀到的資料加上已經讀取的資料足夠拼接成一個數據包,那就將已經讀取的資料拼接上本次讀取的資料,夠成一個完整的業務資料包傳遞到業務邏輯,多餘的資料仍然保留,以便和下次讀到的資料嘗試拼接
Netty半包粘包問題解決
Netty常用編解碼器
- LineBasedFrameDecoder
- 回車換行解碼器 配合StringDecoder
- DelimiterBasedFrameDecoder
- 分隔符解碼器
- FixedLengthFrameDecoder
- 固定長度解碼器
- LengthFieldBasedFrameDecoder
- 基於’長度’解碼器(私有協議最常用)
Netty拆包的基類
- ByteToMessageDecoder
- 自解析
- LengthFieldPrepender
- 長度編碼器
Netty拆包的基類 - ByteToMessageDecoder
內部維護了一個數據累積器cumulation,每次讀取到資料都會不斷累加,然後嘗試對累加到的資料進行拆包,拆成一個完整的業務資料包
每次都將讀取到的資料通過記憶體拷貝的方式, 累積到cumulation中 呼叫子類的decode方法對累積的資料嘗試進行拆包
基於包頭不固定長度的解碼器
基於包頭不固定長度的解碼器:
LengthFieldBasedFrameDecoder 引數說明
maxFrameLength:包的最大長度
lengthFieldOffset:長度屬性的起始位(偏移位),包中存放長度屬性欄位的起始位置
lengthFieldLength:長度屬性的長度
lengthAdjustment:長度調節值,在總長被定義為包含包頭長度時,修正資訊長度
initialBytesToStrip:跳過的位元組數,根據需要跳過lengthFieldLength個位元組,以便接收端直接接受到不含“長度屬性”的內容
LengthFieldPrepender 編碼器
引數說明 lengthFieldLength:長度屬性的位元組長度
lengthIncludesLengthFieldLength:false,長度位元組不算在總長度中,true,算到總長度中
Netty 編解碼
編解碼器的作用就是講原始位元組資料與自定義的訊息物件進行互轉
Decoder(解碼器)
Encoder(編碼器)
支援業界主流的序列化框架
Protobuf
Jboss Marshalling
Java Serialization