3.Netty入门第三章——粘包和拆包

TCP粘包产生原因

  1. 应用程序write写入的字节数大小大于套接字发送缓冲区的大小。
  2. 进行MSS大小的TCP分段。
  3. 以太网帧的payload大于MTU进行IP分片。

用于解决TCP粘包问题的编码器

序号 名字 作用
1 LineBasedFrameDecoder 基于** **的解码器
2 StringDecoder 基于** 字符串 **的解码器
3 DelimiterBasedFrameDecoder 基于** 分隔符 **作为码流结束标示的消息解码器
4 FixedLengthFrameDecoder 基于** 固定长度 **解码器
  1. LineBasedFrameDecoder -- 基于** **的解码器。遍历ByteBuf中的可读字节,判断是否有"\n""\r\n",如有则以此结束位置。可配置单行最大长度,如达到最大长度,仍没有发现换行符,则抛出异常。(见代码片段1)
// 代码片段1
public class TimeServer {
    private class ChildChanneHandler extends ChannelInitiallizer<SocketChannel> {
        @override
        protected void initChannel(SocketChannel arg0) throws Execption { 
            arg0.pipeline().addLast ( new LineBasedFrameDecoder(1024));
            arg0.pipeline().addLast ( new StringDecoder());
            arg0.pipeline().addLast ( new TimeClientHandler());
        }
    }
}
  1. StringDecoder -- 基于** 字符串 **的解码器。将接收到的byte[]转换成字符串。LineBasedFrameDecoder+StringDecoder的组合即为按行切换的文本解码器。
  2. DelimiterBasedFrameDecoder -- 基于** 分隔符 **作为码流结束标示的消息解码器。(见代码片段2)
// 代码片段2
public class EchoServer {
    private class ChildChanneHandler extends ChannelInitiallizer<SocketChannel> {
        @override
        protected void initChannel(SocketChannel arg0) throws Execption { 
            ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes()))
            arg0.pipeline().addLast ( new DelimiterBasedFrameDecoder(1024,delimiter));
            // arg0.pipeline().addLast ( new LineBasedFrameDecoder(1024));
            arg0.pipeline().addLast ( new StringDecoder());
            arg0.pipeline().addLast ( new TimeClientHandler());
        }
    }
}
  1. FixedLengthFrameDecoder -- ** 固定长度 **解码器.(见代码片段3)
// 代码片段3
public class EchoServer {
   private class ChildChanneHandler extends ChannelInitiallizer<SocketChannel> {
       @override
       protected void initChannel(SocketChannel arg0) throws Execption { 
           ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes()))
           // arg0.pipeline().addLast ( new DelimiterBasedFrameDecoder(1024,delimiter));
           // arg0.pipeline().addLast ( new LineBasedFrameDecoder(1024));
           arg0.pipeline().addLast ( new FixedLengthFrameDecoder(20));
           arg0.pipeline().addLast ( new StringDecoder());
           arg0.pipeline().addLast ( new TimeClientHandler());
       }
   }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • RPC框架远程调用的实现方式在原理上是比较简单的,即将调用的方法(接口名、方法名、参数类型、参数)序列化之后发送到...
    谜碌小孩阅读 8,368评论 0 13
  • netty常用API学习 netty简介 Netty是基于Java NIO的网络应用框架. Netty是一个NIO...
    花丶小伟阅读 11,215评论 0 20
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 11,763评论 0 17
  • 上篇文章讲解了客户端与服务端通信示例,本篇来讲解下多客户端之间是如何通信的,我们以一个聊天室的程序为例。具体需求:...
    东升的思考阅读 10,354评论 0 2
  • 求答案
    fc665bc8882a阅读 1,859评论 0 0