Netty中分隔符和定长解码器的应用

2024-06-23 12:32

本文主要是介绍Netty中分隔符和定长解码器的应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一.使用DelimiterBasedFrameDecoder自动完成以分隔符作为结束标志的解码

1.1 DelimiterBasedFrameDecoder服务端开发

1.1.1 EchoServer实现

import io.netty.bootstrap.ServerBootstrap;

import io.netty.buffer.ByteBuf;

import io.netty.buffer.Unpooled;

import io.netty.channel.ChannelFuture;

import io.netty.channel.ChannelInitializer;

import io.netty.channel.ChannelOption;

import io.netty.channel.EventLoopGroup;

importio.netty.channel.nio.NioEventLoopGroup;

importio.netty.channel.socket.SocketChannel;

import io.netty.channel.socket.nio.NioServerSocketChannel;

importio.netty.handler.codec.DelimiterBasedFrameDecoder;

importio.netty.handler.codec.LineBasedFrameDecoder;

importio.netty.handler.codec.string.StringDecoder;

import io.netty.handler.logging.LogLevel;

import io.netty.handler.logging.LoggingHandler;

/*

 * 利用DelimiterBasedFrameDecoder完成以分隔符作为码流结束的标识

 */

public class EchoServer {

        

         publicvoid bind(int port) throws Exception{

                   //配置服务端的NIO线程组

                   EventLoopGroupbossGroup =new NioEventLoopGroup();

                   EventLoopGroupworkerGroup =new NioEventLoopGroup();

         try{

                   //用于启动NIO服务器的辅助启动类,降低服务端的开发复杂度

                   ServerBootstrapb=new ServerBootstrap();

                   b.group(bossGroup,workerGroup).

                   channel(NioServerSocketChannel.class)

                   .option(ChannelOption.SO_BACKLOG,100)

                   .handler(newLoggingHandler(LogLevel.INFO))

                   .childHandler(newChannelInitializer<SocketChannel>() {

                            @Override

                            publicvoid initChannel(SocketChannel ch) throws Exception{

                                     ByteBufdelimiter=Unpooled.copiedBuffer("$_".getBytes());

                                     ch.pipeline().addLast(

                                                        newDelimiterBasedFrameDecoder(1024,delimiter)); // 单条消息最大长度:1024

                                     ch.pipeline().addLast(newStringDecoder());

                                     ch.pipeline().addLast(newEchoServerHandler());

                            }

                            });

                           

                  

                   //绑定端口,同步等待成功

                   ChannelFuturef=b.bind(port).sync();

                   //等待服务端监听端口关闭

                   f.channel().closeFuture().sync();

        

                  

         }catch (Exception e) {

                   //TODO: handle exception

         }finally{

                   //优雅退出,释放线程池资源

                   bossGroup.shutdownGracefully();

                   workerGroup.shutdownGracefully();

         }

        

         }

 

        

         publicstatic void main(String[] args) throws Exception{

                   intport=8080;

                   if(args!=null&&args.length>0){

                            try{

                                     port=Integer.valueOf(args[0]);

                            }catch (NumberFormatException e) {

                                     //TODO: handle exception

                            }

                   }

                   newEchoServer().bind(port);

         }}

1.1.2 EchoServerHandler实现

import io.netty.buffer.ByteBuf;

import io.netty.buffer.Unpooled;

import io.netty.channel.ChannelHandlerAdapter;

import io.netty.channel.ChannelHandlerContext;

/*

 * 利用LineBasedFrameDecoder解决TCP粘包问题

 */

public classEchoServerHandler extends ChannelHandlerAdapter{

     

   int counter =0;

   @Override

   public voidchannelRead(ChannelHandlerContext ctx,Object msg)throwsException{

     

      Stringbody=(String)msg;

      System.out.println("This is"+++counter+"times receive client: ["+body+"]" );

      body+="$_";

         ByteBufecho=Unpooled.copiedBuffer(body.getBytes());

         ctx.writeAndFlush(echo);

   }

 

  

   @Override

   public voidexceptionCaught(ChannelHandlerContext ctx,Throwable cause){

      cause.printStackTrace();

      ctx.close();  // 发生异常,关闭链路

   }

}

1.2 DelimitedBasedFrameDecoder客户端开发

1.2.1 EchoClient实现

import client.TimeClient;

import io.netty.bootstrap.Bootstrap;

import io.netty.buffer.ByteBuf;

import io.netty.buffer.Unpooled;

import io.netty.channel.ChannelFuture;

import io.netty.channel.ChannelInitializer;

import io.netty.channel.ChannelOption;

import io.netty.channel.EventLoopGroup;

importio.netty.channel.nio.NioEventLoopGroup;

importio.netty.channel.socket.SocketChannel;

importio.netty.channel.socket.nio.NioSocketChannel;

importio.netty.handler.codec.DelimiterBasedFrameDecoder;

importio.netty.handler.codec.string.StringDecoder;

 

public class EchoClient {

        

         publicvoid connect(int port,String host) throws Exception{

                   //配置客户端NIO线程组

                   EventLoopGroupgroup=new NioEventLoopGroup();

                   try{

                            Bootstrapb=new Bootstrap();

                            b.group(group).channel(NioSocketChannel.class)

                            .option(ChannelOption.TCP_NODELAY,true)

                            .handler(newChannelInitializer<SocketChannel>() {

                                     @Override

                                     publicvoid initChannel(SocketChannel ch) throws Exception{

                                               ByteBufdelimiter=Unpooled.copiedBuffer("$_".getBytes());

                                               ch.pipeline().addLast(newDelimiterBasedFrameDecoder(1024,delimiter));

                                               ch.pipeline().addLast(newStringDecoder());

                                               ch.pipeline().addLast(newEchoClientHandler());

                                     }

                            });

                            //发起异步连接操作

                            ChannelFuturef=b.connect(host,port).sync();

                            //等待客户端链路关闭

                            f.channel().closeFuture().sync();

                   }catch (Exception e) {

                            //TODO: handle exception

                   }finally{

                            //优雅退出,释放NIO线程组

                            group.shutdownGracefully();

                   }

         }

        

         publicstatic void main(String[] args) throws Exception{

                   intport=8080;

                   if(args!=null&&args.length>0){

                            try{

                                     port=Integer.valueOf(args[0]);

                                    

                            }catch (NumberFormatException e) {

                                     //TODO: handle exception

                                    

                            }

                            newTimeClient().connect(port,"127.0.0.1");

                   }

         }

 

}

1.2.2 EchoClientHandler实现

import io.netty.buffer.Unpooled;

importio.netty.channel.ChannelHandlerAdapter;

importio.netty.channel.ChannelHandlerContext;

 

public class EchoClientHandler extendsChannelHandlerAdapter{

        private int counter;

        static final String ECHO_REQ="Welcome to Netty.$_";

        

        public EchoClientHandler(){

                 

        }

        

        @Override

        public void channelActive(ChannelHandlerContext ctx){

                 for(int i=0;i<10;i++){

                           ctx.writeAndFlush(Unpooled.copiedBuffer(ECHO_REQ.getBytes()));

                 }

        }

        

        public void channelRead(ChannelHandlerContext ctx,Object msg) throwsException{

                 ctx.flush();

        }

        

        @Override

        public voidexceptionCaught(ChannelHandlerContext ctx,Throwable cause){

                 cause.printStackTrace();

                 ctx.close();

        }

}

二.使用FiexLengthFrameDecoder定长解码器进行自动解码

2.1 FixLengthFrameDecoder服务的开发

2.1.1 EchoServer实现

package fixedlength;

import io.netty.bootstrap.ServerBootstrap;

import io.netty.buffer.ByteBuf;

import io.netty.buffer.Unpooled;

import io.netty.channel.ChannelFuture;

import io.netty.channel.ChannelInitializer;

import io.netty.channel.ChannelOption;

import io.netty.channel.EventLoopGroup;

importio.netty.channel.nio.NioEventLoopGroup;

importio.netty.channel.socket.SocketChannel;

importio.netty.channel.socket.nio.NioServerSocketChannel;

importio.netty.handler.codec.DelimiterBasedFrameDecoder;

import io.netty.handler.codec.FixedLengthFrameDecoder;

importio.netty.handler.codec.LineBasedFrameDecoder;

importio.netty.handler.codec.string.StringDecoder;

import io.netty.handler.logging.LogLevel;

importio.netty.handler.logging.LoggingHandler;

/*

 * 利用FixedLengthFrameDecoder固定解码长度

 */

public class EchoServer {

        

         publicvoid bind(int port) throws Exception{

                   //配置服务端的NIO线程组

                   EventLoopGroupbossGroup =new NioEventLoopGroup();

                   EventLoopGroupworkerGroup =new NioEventLoopGroup();

         try{

                   //用于启动NIO服务器的辅助启动类,降低服务端的开发复杂度

                   ServerBootstrapb=new ServerBootstrap();

                   b.group(bossGroup,workerGroup).

                   channel(NioServerSocketChannel.class)

                   .option(ChannelOption.SO_BACKLOG,100)

                   .handler(newLoggingHandler(LogLevel.INFO))

                   .childHandler(newChannelInitializer<SocketChannel>() {

                            @Override

                            publicvoid initChannel(SocketChannel ch) throws Exception{

                                     ByteBufdelimiter=Unpooled.copiedBuffer("$_".getBytes());

                                     ch.pipeline().addLast(

                                                        newFixedLengthFrameDecoder(20)); // 固定解码长度为20

                                     ch.pipeline().addLast(newStringDecoder());

                                     ch.pipeline().addLast(newEchoServerHandler());

                            }

                            });

                           

                  

                   //绑定端口,同步等待成功

                   ChannelFuturef=b.bind(port).sync();

                   //等待服务端监听端口关闭

                   f.channel().closeFuture().sync();

        

                  

         }catch (Exception e) {

                   //TODO: handle exception

         }finally{

                   //优雅退出,释放线程池资源

                   bossGroup.shutdownGracefully();

                   workerGroup.shutdownGracefully();

         }

        

         }

 

        

         publicstatic void main(String[] args) throws Exception{

                   intport=8080;

                   if(args!=null&&args.length>0){

                            try{

                                     port=Integer.valueOf(args[0]);

                            }catch (NumberFormatException e) {

                                     //TODO: handle exception

                            }

                   }

                   newEchoServer().bind(port);

         }

 

}

2.1.2 EchoServerHandler实现

import io.netty.channel.ChannelHandlerAdapter;

import io.netty.channel.ChannelHandlerContext;

/*

 * 打印读取的消息

 */

public classEchoServerHandler extends ChannelHandlerAdapter{

         

   @Override

   public voidchannelRead(ChannelHandlerContext ctx,Object msg)throwsException{

      System.out.println("Receive client:["+msg+"]");

     

   }

   @Override

   public voidexceptionCaught(ChannelHandlerContext ctx,Throwable cause){

      cause.printStackTrace();

      ctx.close();  // 发生异常,关闭链路

   }

}

  利用FixedLengthFrameDecoder解码器,无论一次接受多少数据报,它都会按照构造函数中固定长度进行解码

这篇关于Netty中分隔符和定长解码器的应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1087165

相关文章

利用Python操作Word文档页码的实际应用

《利用Python操作Word文档页码的实际应用》在撰写长篇文档时,经常需要将文档分成多个节,每个节都需要单独的页码,下面:本文主要介绍利用Python操作Word文档页码的相关资料,文中通过代码... 目录需求:文档详情:要求:该程序的功能是:总结需求:一次性处理24个文档的页码。文档详情:1、每个

Java中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例解析

《Java中的分布式系统开发基于Zookeeper与Dubbo的应用案例解析》本文将通过实际案例,带你走进基于Zookeeper与Dubbo的分布式系统开发,本文通过实例代码给大家介绍的非常详... 目录Java 中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例一、分布式系统中的挑战二

Java 缓存框架 Caffeine 应用场景解析

《Java缓存框架Caffeine应用场景解析》文章介绍Caffeine作为高性能Java本地缓存框架,基于W-TinyLFU算法,支持异步加载、灵活过期策略、内存安全机制及统计监控,重点解析其... 目录一、Caffeine 简介1. 框架概述1.1 Caffeine的核心优势二、Caffeine 基础2

使用Node.js和PostgreSQL构建数据库应用

《使用Node.js和PostgreSQL构建数据库应用》PostgreSQL是一个功能强大的开源关系型数据库,而Node.js是构建高效网络应用的理想平台,结合这两个技术,我们可以创建出色的数据驱动... 目录初始化项目与安装依赖建立数据库连接执行CRUD操作查询数据插入数据更新数据删除数据完整示例与最佳

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

PostgreSQL简介及实战应用

《PostgreSQL简介及实战应用》PostgreSQL是一种功能强大的开源关系型数据库管理系统,以其稳定性、高性能、扩展性和复杂查询能力在众多项目中得到广泛应用,本文将从基础概念讲起,逐步深入到高... 目录前言1. PostgreSQL基础1.1 PostgreSQL简介1.2 基础语法1.3 数据库

Python中的filter() 函数的工作原理及应用技巧

《Python中的filter()函数的工作原理及应用技巧》Python的filter()函数用于筛选序列元素,返回迭代器,适合函数式编程,相比列表推导式,内存更优,尤其适用于大数据集,结合lamb... 目录前言一、基本概念基本语法二、使用方式1. 使用 lambda 函数2. 使用普通函数3. 使用 N

Python中yield的用法和实际应用示例

《Python中yield的用法和实际应用示例》在Python中,yield关键字主要用于生成器函数(generatorfunctions)中,其目的是使函数能够像迭代器一样工作,即可以被遍历,但不会... 目录python中yield的用法详解一、引言二、yield的基本用法1、yield与生成器2、yi

Python多线程应用中的卡死问题优化方案指南

《Python多线程应用中的卡死问题优化方案指南》在利用Python语言开发某查询软件时,遇到了点击搜索按钮后软件卡死的问题,本文将简单分析一下出现的原因以及对应的优化方案,希望对大家有所帮助... 目录问题描述优化方案1. 网络请求优化2. 多线程架构优化3. 全局异常处理4. 配置管理优化优化效果1.