熟悉TCP编程的读者可能都知道,无论是服务端还是客户端,当我们读取或者发送消息的时候,都需要考虑TCP底层的粘包/拆包机制。如果不考虑TCP粘包的问题,就可能导致读取数据的错误。本文将讲解如何使用Netty5.0解决TCP粘包/拆包问题。
netty5.0中有一个非常方便的传输解析器:LengthFieldBasedFrameDecoder。下面是LengthFieldBasedFrameDecoder的构造方法
/**
* Creates a new instance.
*
* @param maxFrameLength
* the maximum length of the frame. If the length of the frame is
* greater than this value, {@link TooLongFrameException} will be
* thrown.
* @param lengthFieldOffset
* the offset of the length field
* @param lengthFieldLength
* the length of the length field
* @param lengthAdjustment
* the compensation value to add to the value of the length field
* @param initialBytesToStrip
* the number of first bytes to strip out from the decoded frame
*/
public LengthFieldBasedFrameDecoder(
int maxFrameLength,
int lengthFieldOffset, int lengthFieldLength,
int lengthAdjustment, int initialBytesToStrip) {
this(
maxFrameLength,
lengthFieldOffset, lengthFieldLength, lengthAdjustment,
initialBytesToStrip, true);
}
maxFrameLength:数据包最大允许长度
lengthFieldOffset:长度字段的偏移量
lengthFieldLength:长度字段的长度
lengthAdjustment:补位值
initialBytesToStrip:从解码器中剔除的长度(设置为上面长度字段的长度)
这样看来,只需在netty服务端添加一个解析器就可以解决TCP粘包问题。服务端代码就不全贴上来了,只贴上有变动的部分,不明白的读者请看一下前两篇netty文章。
bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel)
throws Exception {
ChannelPipeline p = socketChannel.pipeline();
// 定义传输解析器,数据包前加4个字节表示包的总长度
p.addLast(new LengthFieldBasedFrameDecoder(1024 * 1024, 0,
4, 0, 4));
// 维持心跳
p.addLast(new IdleStateHandler(15, 30, 30, TimeUnit.SECONDS));
p.addLast(new NettyIdleStateHandler());
p.addLast(new NettyServerHandler());
}
});
添加解析器后,只需要按照约定往服务器发送数据包时在数据包头部添加一个值来说明后面数据的字节长度即可。
客户端发送数据包时格式如下:
public static ByteBuf newProtocol(String message)
throws UnsupportedEncodingException {
byte[] req = message.getBytes(Constant.UTF8);
ByteBuf pingMessage = Unpooled.buffer();
pingMessage.writeInt(req.length);
pingMessage.writeBytes(req);
return pingMessage;
}
如此TCP粘包/拆包问题即可轻松愉快的解决。
分享到:
相关推荐
主要介绍了使用Netty解决TCP粘包和拆包问题过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
采用Netty5.0编的的TCP/IP上传文件的列子,实现了拆包,合并
本实例是《Netty 粘包/半包原理与拆包实战》 一文的源代码工程。 大家好,我是作者尼恩。 在前面的文章中,完成了一个高性能的 Java 聊天程序,尼恩已经再一次的进行了通讯协议的选择。放弃了大家非常熟悉的json ...
什么是粘包拆包,为什么发生拆包粘包问题,如何处理拆包粘包问题
Netty5.0jar包带javadoc Netty4.03API文档CHM格式
官方自带的netty5.0案例,非常强大,学习netty必备!
- 本实例是《Netty 粘包/半包原理与拆包实战》 一文的源代码工程。 大家好,我是作者尼恩。 在前面的文章中,完成了一个高性能的 Java 聊天程序,尼恩已经再一次的进行了通讯协议的选择。放弃了大家非常熟悉的json...
Netty粘包与拆包源码
Netty 入门与实战:仿写微信 IM 即时通讯系统
服务器条件NETTY框架编程: 服务器IP:192.168.2.106 端口8810 数据传输的方式:从串口接收到一条完整的协议数据,计算出数据字节长度,打包成HtAlingProtocol类,并发送给服务器; package ...
Netty在Android开发中的应用实战系列(一)——— 搭建服务端与客户端:...Netty在Android开发中的应用实战系列(四)——— 粘包 | 拆包 处理:https://azhon.blog.csdn.net/article/details/101039462
netty5.0架构剖析和源码解读, 很清楚的讲解了netty5.0的架构和源码
Netty5.0架构剖析和源码解读,学习NIO,学习netty,值得学习
Netty 入门与实战:仿写微信 IM 即时通讯系统,掘金小册子,netty教程。章节齐全无缺失,排版非常不错。 1.仿微信IM系统简介 1 2.Netty是什么? 2 3.服务端启动流程 8 4.客户端启动流程 11 5.实战:客户端与服务端双向...
手写RPC框架 说明:https://blog.csdn.net/lan861698789/article/details/103837228
《Netty进阶之路:跟着案例学Netty》中的案例涵盖了Netty...在案例的分析过程中,还穿插讲解了Netty的问题定位思路、方法、技巧,以及解决问题使用的相关工具,对读者在实际工作中用好Netty具有很大的帮助和启发作用。
Netty中粘包和拆包的解决方案.docx
Netty5.0 架构剖析和源码解读 作者:李林锋 版权所有 email neu_lilinfeng@ © Netty5.0 架构剖析和源码解读1 1. 概述2 1.1. JAVA 的IO演进2 1.1.1. 传统BIO通信的弊端2 1.1.2. Linux 的网络IO模型简介4 1.1.3. IO...
基于Netty5.0的高级案例NettyWebsocket,详情请参见博文:http://blog.csdn.net/l1028386804/article/details/55026558