之前为了调式和方便一直没有处理粘包的问题,今天专门花了时间来搞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了
什么是大端小端,其实这个叫法有点坑爹 会给人造成混乱,因为 端 对于中国人来说 有开始的意思 以后 这样叫吧 小尾,大尾
小尾就是 低地址存 数据的高位 高低地址存数据的地位 什么鬼意思呢
看图
看 小端模式 都是高地址存小数据
小端 就是小尾巴 大端就是大尾巴。