所谓的粘包/拆包,用一个例子来说明就是:
加入客户端向服务端发送1000条数据,如果不加以处理的话,那么服务端接收的数据可能就是如图所示了:
数据要么几段粘在了一起,要么一段数据被拆成了几段,这肯定会造成很大的影响。
而解决后的所接收的正确数据该如下所示:
简单讲了一下粘包/拆包是什么样的问题,详细解释可见csdn博客
http://blog.csdn.net/binghuazh/article/details/4222516
客户端代码:
package com.netty.dealpacket; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import java.nio.ByteBuffer; /** * @author Chalmers 2016年2月24日 下午2:35:39 */ public class Client { public static void main(String[] args) throws UnknownHostException, IOException { Socket socket = new Socket("127.0.0.1", 9090); String message = "hello"; byte[] bytes = message.getBytes(); // 设置空间大小为一个存储了长度的int型数据(长度)加上转换后的byte数组 ByteBuffer buffer = ByteBuffer.allocate(4 + bytes.length); // 将长度存入 buffer.putInt(bytes.length); // 将数据存入 buffer.put(bytes); // 转换成字节数组 byte[] array = buffer.array(); // 向服务端发送1000次 for (int i = 0; i < 1000; i++) { socket.getOutputStream().write(array); } // 关闭 socket.close(); } }
处理问题代码:
package com.netty.dealpacket; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.handler.codec.frame.FrameDecoder; /** * @author Chalmers 2016年2月24日 下午2:23:49 */ public class MyDecoder extends FrameDecoder { @Override protected Object decode(ChannelHandlerContext chc, Channel channel, ChannelBuffer buffer) throws Exception { // 如果buffer中的可读字节大于4个(即除了长度以外还有数据,因为长度可能是为0的) if (buffer.readableBytes() > 4) { // 标记,指向当前指针位置,读取数据时使用 buffer.markReaderIndex(); // 取得长度 int len = buffer.readInt(); // 如果剩余可读字节小于长度的话,则表明发生了拆包现象,那么不对它进行处理 if (buffer.readableBytes() < len) { // 重置标记 buffer.resetReaderIndex(); // 返回null,表示等待 return null; } // 对数据进行处理 byte[] bytes = new byte[len]; buffer.readBytes(bytes); // 将数据返回到ServerHandler中进行处理 return new String(bytes); } return null; } }
package com.netty.dealpacket; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelHandler; /** * @author Chalmers 2016年2月24日 下午2:22:41 */ public class ServerHandler extends SimpleChannelHandler { int count = 1; @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { // 对从MyDecoder中传递过来的数据进行处理 System.out.println((String) e.getMessage() + " " + count); count++; } }
服务端代码:
package com.netty.dealpacket; import java.net.InetSocketAddress; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.Channels; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; import org.jboss.netty.handler.codec.string.StringEncoder; /** * @author Chalmers 2016年2月24日 下午2:21:33 */ public class Server { public static void main(String[] args) { ServerBootstrap serverBootstrap = new ServerBootstrap(); ExecutorService boss = Executors.newCachedThreadPool(); ExecutorService worker = Executors.newCachedThreadPool(); serverBootstrap.setFactory(new NioServerSocketChannelFactory(boss, worker)); serverBootstrap.setPipelineFactory(new ChannelPipelineFactory() { @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline pipeline = Channels.pipeline(); pipeline.addLast("decoder", new MyDecoder()); pipeline.addLast("encoder", new StringEncoder()); pipeline.addLast("handler", new ServerHandler()); return pipeline; } }); serverBootstrap.bind(new InetSocketAddress(9090)); System.out.println("start..."); } }
相关推荐
主要介绍了使用Netty解决TCP粘包和拆包问题过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
什么是粘包拆包,为什么发生拆包粘包问题,如何处理拆包粘包问题
netty搭建tcp服务,并以相应的编码解决粘包,拆包问题
第4章 TCP粘包/拆包问题解析之道 第5章 分隔符和定长解析码器的应用 第6章 编码技术 第7章 MessagePack 编解码 第8章 Google Protobuf编解码 第9章 JBoss Marshalling 编解码 第10章 HTTP协议开发应用 第11章 ...
注:下载前请查看本人博客文章,看是否...里面包含模拟TCP客户端发送报文工具,硬件厂商提供的协议,服务端(springboot+netty)解析报文源码,源码里整合了redis,不需要可自行删除,如有需要客户端代码,可联系我。
2.NIO 的组成 4.Netty 的线程模型 5.TCP 粘包/拆包的原因及解决方法 6.了解哪几种序列化协议
报文格式8位长度加内容,代码还对netty的粘包和拆包做了处理
1.BIO、NIO 和 AIO 的区别?...5.TCP 粘包/拆包的原因及解决方法? 6.了解哪几种序列化协议? 7.如何选择序列化协议? 8.Netty 的零拷贝实现? 9.Netty 的高性能表现在哪些方面? 10.NIOEventLoopGroup 源码?
Netty编码器和处理程序的调用机制,TCP粘包和拆包及其解决方法,Netty核心代码剖析,最后自己手动10天左右的时间学完,确实需要对Java编程有一定基础要求,自己也是所有人匪浅。非常感谢尚硅谷韩顺平老师!!!!! ...
TCP粘包、拆包 2)编解码技术 1)Java序列化 2)业界主流的编解码框架 Thrift Protobuf 3) Websocket 5)Netty协议栈功能设计 6)Netty源码分析 ByteBuf工作原理 Channel, Unsafe ChannelPipline, ChannelHandler ...
第4 章 TCP 粘包/拆包问题的解决之道...... 79 第5 章 分隔符和定长解码器的应用...... 93 第6 章 编解码技术...... 106 第7 章 MessagePack 编解码...... 118 第8 章 Google Protobuf ...
Netty的技术的总结(Marshalling编解码,tcp的拆包粘包,webservice),包括新手入门源码,注释清楚,绝对物超所值,从入门到最后的实战,需要交流的可以私信我
86_Netty自定义编解码器与TCP粘包拆包问题;87_Netty编解码器执行流程深入分析;88_ReplayingDecoder源码分析与特性解读;89_Netty常见且重要编解码器详解;90_TCP粘包与拆包实例演示及分析;91_Netty自定义协议与...
TCP粘包/拆包 TCP是个流协议,所谓流,就是没有界限的一串数据。大家可以想想河流里的流水,它们是连成一片的,其间并没有分界线。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分...
netty-frameDecoder换行符,自定义分隔符,定长度解码器说明使用tcp传送数据,由于缓存区大小的设置,MSS的tcp分段等因素,数据传输时会出现TCP粘包/拆包的问题。但是底层的tcp无法理解上层的业务数据,所以在底层也...
解决TCP粘包/拆包问题;支持非双向的同步/异步调用;基于ProtoStuff的对象序列化;完整的单元测试和JMH性能压测;基于ZooKeeper实现的服务注册和发现;仿Dubbo数据包结构,优化协议头仅20字节;支持4种负载均衡策略...
Netty在Android开发中的应用实战系列(一)——— 搭建服务端与客户端:...Netty在Android开发中的应用实战系列(四)——— 粘包 | 拆包 处理:https://azhon.blog.csdn.net/article/details/101039462
Netty框架中LineBasedFrameDecoder分隔符解码器解决考虑TCP的粘包与拆包问题。依次编译bytebuf中的可读字符,判断看是否有“\n”或者“\r\n”,如果有,就以此位置为结束位置,从可读索引到结束位置区间的字节就组成...