netty 粘包问题处理
来源:互联网 发布:linux内核优化 编辑:程序博客网 时间:2024/05/16 01:26
一般TCP粘包/拆包解决办法
- 定长消息,例如每个报文长度固定,不够补空格
- 使用回车换行符分割,在包尾加上分割符,例如Ftp协议
- 消息分割,头为长度(消息总长度或消息体长度),通常头用一个int32表示
- 复杂的应用层协议
netty的几种解决方案
特殊分隔符解码器:DelimiterBasedFrameDecoder
客户端发送消息
String message = "netty is a nio server framework &" +"which enables quick and easy development &" +"of net applications such as protocol &" +"servers and clients!";
服务端添加解码器:DelimiterBasedFrameDecoder
ByteBuf delimiter = Unpooled.copiedBuffer("&".getBytes());ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,delimiter));//1024表示单条消息的最大长度,解码器在查找分隔符的时候,达到该长度还没找到的话会抛异常ch.pipeline().addLast(new StringDecoder());....ch.pipeline().addLast(new StringEncoder());
打印输出:
接收消息:[netty is a nio server framework ]接收消息:[which enables quick and easy development ]接收消息:[of net applications such as protocol]接收消息:[servers and clients!]
参数解释:
public DelimiterBasedFrameDecoder(int maxFrameLength, ByteBuf delimiter) { this(maxFrameLength, true, delimiter);}maxFrameLength:解码的帧的最大长度stripDelimiter:解码时是否去掉分隔符failFast:为true,当frame长度超过maxFrameLength时立即报TooLongFrameException异常,为false,读取完整个帧再报异常delimiter:分隔符
定长解码器:FixedLengthFrameDecoder
参数说明:
- frameLength:帧的固定长度
服务端
ch.pipeline().addLast(new FixedLengthFrameDecoder(30));//设置定长解码器 长度设置为30public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("接收客户端msg:["+msg+"]"); ByteBuf echo=Unpooled.copiedBuffer(MESSAGE.getBytes()); ctx.writeAndFlush(echo);}
客户端
ch.pipeline().addLast(new FixedLengthFrameDecoder(30));//设置定长解码器
基于包头不固定长度的解码器:LengthFieldBasedFrameDecoder
参数说明
- maxFrameLength:解码的帧的最大长度
- lengthFieldOffset:长度属性的起始位(偏移位),包中存放有整个大数据包长度的字节,这段字节的其实位置
- lengthFieldLength:长度属性的长度,即存放整个大数据包长度的字节所占的长度
- lengthAdjustmen:长度调节值,在总长被定义为包含包头长度时,修正信息长度。
- initialBytesToStrip:跳过的字节数,根据需要我们跳过lengthFieldLength个字节,以便接收端直接接受到不含“长度属性”的内容
- failFast :为true,当frame长度超过maxFrameLength时立即报TooLongFrameException异常,为false,读取完整个帧再报异常
备注:如果长度解析失误,(过大,就直接丢弃这个包;过小,1、netty不抛出异常;2、校验通不过)
源码:int frameLengthInt = (int) frameLength;if (in.readableBytes() < frameLengthInt) { return null;}
封包时配合使用LengthFieldPrepender,很容易加上包长度
包头添加总包长度字节:LengthFieldPrepender
在发布时,自动在帧的头部加上长度
参数说明:
- lengthFieldLength:长度属性的字节长度
lengthIncludesLengthFieldLength:false,长度字节不算在总长度中,true,算到总长度中
应用:
pipeline.addLast("frameEncode", new LengthFieldPrepender(4, false));
官方说明:
编码类,自动将+----------------+ | "HELLO, WORLD" | +----------------+格式的数据转换成如下格式的数据, +--------+----------------+ + 0x000C | "HELLO, WORLD" | +--------+----------------+如果lengthIncludesLengthFieldLength设置为true,则编码为(多了两个字节)+--------+----------------+ + 0x000E | "HELLO, WORLD" | +--------+----------------+
0 0
- netty 粘包问题处理
- netty中的粘包和拆包问题处理
- netty处理粘包问题——1
- netty处理粘包问题——2
- java netty使用DelimiterBasedFrameDecoder处理tcp粘包问题
- netty的粘包 解包问题
- netty处理粘包问题用特殊字符分割——3
- Netty使用LineBasedFrameDecoder解决粘包问题
- netty 数据分包、组包、粘包处理机制
- Netty的入门-拆包和粘包的处理
- Netty中处理TCP粘包和拆包
- Netty自定义协议的粘包和拆包处理
- netty 数据分包、组包、粘包处理
- Netty中处理TCP粘包和拆包
- netty拆包粘包问题处理
- Netty初探-解决TCP粘包/拆包问题
- 聊一聊Netty TCP粘包/拆包问题的解决办法
- Netty实践(二):TCP拆包、粘包问题
- scala 学习总结(一): implicit 函数的使用
- Hand DoFs
- c# 导出excel 组件比较(npoi vs openxml)
- aes加密文件
- web.xml配置详解
- netty 粘包问题处理
- Java 拷贝文件夹
- iOS开发实用知识点记录(持续更新)
- Arduino软串口调试
- FFmpeg 基本用法
- Codeforces Round #301 (Div. 2) C. Ice Cave(BFS)
- JavaScript探秘:for-in循环(for-in Loops)
- 《机器学习》学习笔记之决策树
- 浅析Python中的struct模块