之前為了調式和方便一直沒有處理粘包的問題,今天專門花了時間來搞NETTY的粘包處理,要知道在高並發下,不處理粘包是不可能的,數據流的混亂會造成業務的崩潰什么的我就不說了。所以這個問題 在我心里一直是個結。
使用NETTY真的很幸福,以前用C寫服務端 還的自己處理粘包的問題 各種痛苦 不過那也是基本功 沒辦法的事情。
在NETTY里面 有幾個拆個包器 我使用的是 LengthFileldBasedFrameDecoder,這個用來解析帶有長度屬性的包,只要我們在傳輸協議中加入包的總長度就行
arg0.pipeline().addFirst("decoder", new LengthFieldBasedFrameDecoder(1024,0,4,0,4));
arg0.pipeline().addLast(new TestInListener());
LengthFieldBasedFrameDecoder
幾個參數的意思
1、最大長度
2-3、描述包長,因為我用的4個字節描述整個包的長度 這里就告訴拆包器 前4個字節描述的包長
4-5、如果整個包長的長度值包含了 包頭的4個字節,那么告訴拆包器從0開始到第4個字節不用截取
最后拆包器拆完包就是調用handler.這里拿到的數據流就是已經截取好的內容了,沒有包含前4個字節了
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { String resultStr=""; //先轉成NETTY buf ByteBuf result = (ByteBuf) msg; //全部數據 byte[] allDataByte = new byte[result.readableBytes()]; //轉成BYTE數組 result.readBytes(allDataByte); resultStr = new String(allDataByte,"UTF-8"); }
好了 現在說說 我遇到的問題
首先 服務端是用NETTY 但是客戶端是C# 之前沒有用拆包器的時候 讀取前4個字節沒有什么問題 加了拆包器就出了問題,原因是,
C#那邊發送的整個包 是小端模式 造成NETTY拿到包后 拆了前4個字節,解出來的長度錯誤~NETTY那邊是不處理這個的,
所以C#發送之前 把前個4字節 轉成大端 就OK了
什么是大端小端,其實這個叫法有點坑爹 會給人造成混亂,因為 端 對於中國人來說 有開始的意思 以后 這樣叫吧 小尾,大尾
小尾就是 低地址存 數據的高位 高低地址存數據的地位 什么鬼意思呢
看圖
看 小端模式 都是高地址存小數據
小端 就是小尾巴 大端就是大尾巴。