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 Flask 库及应用场景

《PythonFlask库及应用场景》Flask是Python生态中​轻量级且高度灵活的Web开发框架,基于WerkzeugWSGI工具库和Jinja2模板引擎构建,下面给大家介绍PythonFl... 目录一、Flask 库简介二、核心组件与架构三、常用函数与核心操作 ​1. 基础应用搭建​2. 路由与参

Spring Boot中的YML配置列表及应用小结

《SpringBoot中的YML配置列表及应用小结》在SpringBoot中使用YAML进行列表的配置不仅简洁明了,还能提高代码的可读性和可维护性,:本文主要介绍SpringBoot中的YML配... 目录YAML列表的基础语法在Spring Boot中的应用从YAML读取列表列表中的复杂对象其他注意事项总

电脑系统Hosts文件原理和应用分享

《电脑系统Hosts文件原理和应用分享》Hosts是一个没有扩展名的系统文件,当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从Hosts文件中寻找对应的IP地址,一旦找到,系统会立即打开对应... Hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址域名与其对应

CSS 样式表的四种应用方式及css注释的应用小结

《CSS样式表的四种应用方式及css注释的应用小结》:本文主要介绍了CSS样式表的四种应用方式及css注释的应用小结,本文通过实例代码给大家介绍的非常详细,详细内容请阅读本文,希望能对你有所帮助... 一、外部 css(推荐方式)定义:将 CSS 代码保存为独立的 .css 文件,通过 <link> 标签

Python使用Reflex构建现代Web应用的完全指南

《Python使用Reflex构建现代Web应用的完全指南》这篇文章为大家深入介绍了Reflex框架的设计理念,技术特性,项目结构,核心API,实际开发流程以及与其他框架的对比和部署建议,感兴趣的小伙... 目录什么是 ReFlex?为什么选择 Reflex?安装与环境配置构建你的第一个应用核心概念解析组件

C#通过进程调用外部应用的实现示例

《C#通过进程调用外部应用的实现示例》本文主要介绍了C#通过进程调用外部应用的实现示例,以WINFORM应用程序为例,在C#应用程序中调用PYTHON程序,具有一定的参考价值,感兴趣的可以了解一下... 目录窗口程序类进程信息类 系统设置类 以WINFORM应用程序为例,在C#应用程序中调用python程序

Java应用如何防止恶意文件上传

《Java应用如何防止恶意文件上传》恶意文件上传可能导致服务器被入侵,数据泄露甚至服务瘫痪,因此我们必须采取全面且有效的防范措施来保护Java应用的安全,下面我们就来看看具体的实现方法吧... 目录恶意文件上传的潜在风险常见的恶意文件上传手段防范恶意文件上传的关键策略严格验证文件类型检查文件内容控制文件存储

CSS3 布局样式及其应用举例

《CSS3布局样式及其应用举例》CSS3的布局特性为前端开发者提供了无限可能,无论是Flexbox的一维布局还是Grid的二维布局,它们都能够帮助开发者以更清晰、简洁的方式实现复杂的网页布局,本文给... 目录深入探讨 css3 布局样式及其应用引言一、CSS布局的历史与发展1.1 早期布局的局限性1.2

在React聊天应用中实现图片上传功能

《在React聊天应用中实现图片上传功能》在现代聊天应用中,除了文字和表情,图片分享也是一个重要的功能,本文将详细介绍如何在基于React的聊天应用中实现图片上传和预览功能,感兴趣的小伙伴跟着小编一起... 目录技术栈实现步骤1. 消息组件改造2. 图片预览组件3. 聊天输入组件改造功能特点使用说明注意事项

Redis中RedisSearch使用及应用场景

《Redis中RedisSearch使用及应用场景》RedisSearch是一个强大的全文搜索和索引模块,可以为Redis添加高效的搜索功能,下面就来介绍一下RedisSearch使用及应用场景,感兴... 目录1. RedisSearch的基本概念2. RedisSearch的核心功能(1) 创建索引(2