服务端NETTY 客户端非NETTY处理粘包和拆包的问题

之前为了调式和方便一直没有处理粘包的问题,今天专门花了时间来搞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了

什么是大端小端,其实这个叫法有点坑爹 会给人造成混乱,因为 端 对于中国人来说 有开始的意思 以后 这样叫吧 小尾,大尾  

小尾就是 低地址存 数据的高位 高低地址存数据的地位 什么鬼意思呢

看图

 

看 小端模式 都是高地址存小数据

小端 就是小尾巴 大端就是大尾巴。

 

LengthFieldBasedFrameDecoder  的报错
Adjusted frame length exceeds

一定要清楚字节序
new LengthFieldBasedFrameDecoder(
ByteOrder.LITTLE_ENDIAN,//字节序
20*1024,
0,
4,
0,
4,
true
)

第一个参数就是字节序,服务端和客户端要一样


字节序一定要一致,网络传输默认的都是大端序.但为什么会出现一组数据中,字节序不一致?

        let buffer = Buffer.from(JSON.stringify(sendData));
        let lenBuf = Buffer.alloc(4);
        //需要发送的数据长度
        let needLen = buffer.length+4;
        //数据长度
        lenBuf.writeInt32LE(needLen);
        //开辟新的内存块
        let newBuf = Buffer.alloc(needLen);
        lenBuf.copy(newBuf,0,0,4);

        buffer.copy(newBuf, 4, 0, buffer.length);

        this._debugProxySock.write(newBuf);
        
上面的js代码,很明显把包头大小设置了成了小端writeInt32LE,但所有框架啊,系统啊,什么的,都是按大端发送的,所以,这数据发出去。别人解析的时候就会有问题,当然,明确解析时的字节序也不会有问题,只是会造成一些麻烦和困惑,所以,必须要一致。




 

posted @ 2016-08-31 23:57  方东信  阅读(2477)  评论(0编辑  收藏  举报