netty: 解决粘包拆包: 分隔符DelimiterBasedFrameDecoder,定长消息FixedLengthFrameDecoder

DelimiterBasedFrameDecoder 自定义分隔符

给Server发送多条信息,但是server会讲多条信息合并为一条。这时候我们需要对发生的消息指定分割,让client和server都知道这些消息是一条一条的

//设置连接符/分隔符,换行显示
ByteBuf buf = Unpooled.copiedBuffer("$_".getBytes());
//DelimiterBasedFrameDecoder:自定义分隔符
sc.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, buf));
				
//设置为字符串形式的解码:将传递的buf改为String
sc.pipeline().addLast(new  StringDecoder());
	
//处理消息			
sc.pipeline().addLast(new ClientHandler());

  

整体代码:

public static void main(String[] args) throws InterruptedException {
		
		EventLoopGroup worker = new NioEventLoopGroup();
		Bootstrap b = new Bootstrap();
		b.group(worker)
		.channel(NioSocketChannel.class)
		.handler(new ChannelInitializer<SocketChannel>() {

			@Override
			protected void initChannel(SocketChannel sc) throws Exception {
				// TODO Auto-generated method stub
				//设置连接符/分隔符,换行显示
				ByteBuf buf = Unpooled.copiedBuffer("$_".getBytes());
				//DelimiterBasedFrameDecoder:自定义分隔符
				sc.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, buf));
				
				//设置为字符串形式的解码:将传递的buf改为String
				sc.pipeline().addLast(new  StringDecoder());
				
				sc.pipeline().addLast(new ClientHandler());
			}
		});
		//连接端口
		ChannelFuture cf = b.connect("127.0.0.1", 8765).sync();
		cf.channel().writeAndFlush(Unpooled.copiedBuffer("aaa$_".getBytes()));
		cf.channel().writeAndFlush(Unpooled.copiedBuffer("bbbbb$_".getBytes()));
		cf.channel().writeAndFlush(Unpooled.copiedBuffer("cccccccc$_".getBytes()));
		
		cf.channel().closeFuture().sync();		
		worker.shutdownGracefully();
		
	}

  

FixedLengthFrameDecoder 定长消息:及发送的消息需要一定的长度,当长度不够时,剩下的消息将会被丢弃,只能通过补空格来防止被丢弃

//自定义长度,换行显示
//设置每次发送长度为5个字符
sc.pipeline().addLast(new FixedLengthFrameDecoder(5));
				
//设置为字符串形式的解码:将传递的buf改为String
sc.pipeline().addLast(new  StringDecoder());
	
//处理消息			
sc.pipeline().addLast(new ClientHandler());

  

完整代码

public static void main(String[] args) throws InterruptedException {
		
		EventLoopGroup worker = new NioEventLoopGroup();
		Bootstrap b = new Bootstrap();
		b.group(worker)
		.channel(NioSocketChannel.class)
		.handler(new ChannelInitializer<SocketChannel>() {

			@Override
			protected void initChannel(SocketChannel sc) throws Exception {
				// TODO Auto-generated method stub
				//设置定长长度为5个字符,换行显示		
                                //每次发送消息的长度需要是5的倍数	
				sc.pipeline().addLast(new FixedLengthFrameDecoder(5));
				
				//设置为字符串形式的解码:将传递的buf改为String
				sc.pipeline().addLast(new  StringDecoder());
				
				sc.pipeline().addLast(new ClientHandler());
			}
		});
		//连接端口
		ChannelFuture cf = b.connect("127.0.0.1", 8765).sync();
		
//打印为:aaaaa
//打印为:bb被丢弃,未满5个长度
cf.channel().writeAndFlush(Unpooled.copiedBuffer("aaaaabb".getBytes()));
		
//打印为:bbbbb
//打印完:ccccc
cf.channel().writeAndFlush(Unpooled.copiedBuffer("bbbbbccccc".getBytes()));

//打印为:ddddd
//打印完:dd空格空格空格
cf.channel().writeAndFlush(Unpooled.copiedBuffer("ddddddd 
  ".getBytes()));
		
		cf.channel().closeFuture().sync();		
		worker.shutdownGracefully();
		
	}

  

原文地址:https://www.cnblogs.com/achengmu/p/10944565.html