• 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();
    		
    	}
    

      

  • 相关阅读:
    Redis设计与实现第一部分:第5章:Redis 跳跃表
    根据临时表修改主表的某字段数据根据主表的主键
    Redis设计与实现第一部分:第2章:简单动态字符串SDS
    Redis
    MySQL的访问控制与用户管理
    MySQL字符集和语言的基础知识
    生成日志文件
    Python进阶09 动态类型
    Python进阶08 异常处理
    Python进阶07 函数对象
  • 原文地址:https://www.cnblogs.com/achengmu/p/10944565.html
Copyright © 2020-2023  润新知