1. 編解碼技術
通常我們也習慣將編碼(Encode)稱為序列化(serialization)苹丸,它將對象序列化為字節(jié)數(shù)組检痰,用于網(wǎng)絡傳輸包归、數(shù)據(jù)持久化或者其它用途。
反之铅歼,解碼(Decode)/反序列化(deserialization)把從網(wǎng)絡公壤、磁盤等讀取的字節(jié)數(shù)組還原成原始對象(通常是原始對象的拷貝),以方便后續(xù)的業(yè)務邏輯操作谭贪。
2 Netty編解碼框架
2.1 LineBasedFrameDecoder解碼器
LineBasedFrameDecoder是回車換行解碼器境钟,如果用戶發(fā)送的消息以回車換行符作為消息結(jié)束的標識,則可以直接使用Netty的 LineBasedFrameDecoder對消息進行解碼俭识,只需要在初始化Netty服務端或者客戶端時將LineBasedFrameDecoder 正確的添加到ChannelPipeline中即可慨削,不需要自己重新實現(xiàn)一套換行解碼器。
LineBasedFrameDecoder的工作原理是它依次遍歷ByteBuf中的可讀字節(jié)套媚,判斷看是否有“\n”或者“\r\n”缚态,如果有,就以此位置為結(jié)束位置堤瘤,從可讀索引到結(jié)束位置區(qū)間的字節(jié)就組成了一行玫芦。它是以換行符為結(jié)束標志的解碼器,支持攜帶結(jié)束符或者不攜帶結(jié)束符兩種解碼方式本辐,同 時支持配置單行的最大長度桥帆。如果連續(xù)讀取到最大長度后仍然沒有發(fā)現(xiàn)換行符医增,就會拋出異常,同時忽略掉之前讀到的異常碼流老虫。防止由于數(shù)據(jù)報沒有攜帶換行符導 致接收到ByteBuf無限制積壓叶骨,引起系統(tǒng)內(nèi)存溢出。
它的使用效果如下:
解碼之前:
+-----------------------------------------------------+
接收到的數(shù)據(jù)報
“This is a netty example for using the nio framework.\r\n When you“
+-----------------------------------------------------+
解碼之后的文本消息
“This is a netty example for using the nio framework.“
+------------------------------------------------- ---+
2.2 DelimiterBasedFrameDecoder解碼器
DelimiterBasedFrameDecoder是分隔符解碼器祈匙,用戶可以指定消息結(jié)束的分隔符忽刽,它可以自動完成以分隔符作為碼流結(jié)束標識的消息的解碼《嵊回車換行解碼器實際上是一種特殊的DelimiterBasedFrameDecoder解碼器跪帝。
分隔符的指定:與大家的習慣不同,分隔符并非以char或者string作為構(gòu)造參數(shù)些阅,而是ByteBuf伞剑,下面我們就結(jié)合實際例子給出它的用法。
假如消息以“$_”作為分隔符扑眉,服務端或者客戶端初始化ChannelPipeline的代碼實例如下:
@Override
public void initChannel(SocketChannel ch)
throws Exception {
ByteBuf delimiter = Unpooled.copiedBuffer("$_"
.getBytes());
ch.pipeline().addLast(
new DelimiterBasedFrameDecoder(1024,
delimiter));
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new UserServerHandler());
}
首先將“$_”轉(zhuǎn)換成ByteBuf對象纸泄,作為參數(shù)構(gòu)造DelimiterBasedFrameDecoder,將其添加到 ChannelPipeline中腰素,然后依次添加字符串解碼器(通常用于文本解碼)和用戶Handler聘裁,請注意解碼器和Handler的添加順序,如果 順序顛倒弓千,會導致消息解碼失敗衡便。
DelimiterBasedFrameDecoder原理分析:解碼時,判斷當前已經(jīng)讀取的ByteBuf中是否包含分隔符ByteBuf洋访,如果包含镣陕,則截取對應的ByteBuf返回。
2.3 FixedLengthFrameDecoder解碼器
FixedLengthFrameDecoder是固定長度解碼器姻政,它能夠按照指定的長度對消息進行自動解碼呆抑,開發(fā)者不需要考慮TCP的粘包/拆包等問題,非常實用汁展。
對于定長消息鹊碍,如果消息實際長度小于定長,則往往會進行補位操作食绿,它在一定程度上導致了空間和資源的浪費侈咕。但是它的優(yōu)點也是非常明顯的,編解碼比較簡單器紧,因此在實際項目中仍然有一定的應用場景耀销。
利用FixedLengthFrameDecoder解碼器,無論一次接收到多少數(shù)據(jù)報铲汪,它都會按照構(gòu)造函數(shù)中設置的固定長度進行解碼熊尉,如果是半包消息罐柳,F(xiàn)ixedLengthFrameDecoder會緩存半包消息并等待下個包到達后進行拼包,直到讀取到一個完整的包帽揪。
我的Github項目硝清,歡迎大家指導!Watch转晰!Star!Fork! Thanks士飒!
GitHub-Netty-demo-server
GitHub-Netty-demo-client