erp办公软件,网站怎么自己优化,头像设计logo,wordpress交流文章目录 概念概述StringEncoderStringDecoder Code源码分析StringEncoderStringDecoder 小结 概念 概述
Netty是一个高性能的网络应用程序框架#xff0c;它提供了丰富的功能#xff0c;包括编解码器#xff0c;这些编解码器用于在网络中发送和接收数据时进行数据的编码和… 文章目录 概念概述StringEncoderStringDecoder Code源码分析StringEncoderStringDecoder 小结 概念 概述
Netty是一个高性能的网络应用程序框架它提供了丰富的功能包括编解码器这些编解码器用于在网络中发送和接收数据时进行数据的编码和解码。
在Netty中StringEncoder和StringDecoder是两个常用的编解码器它们的功能和用途如下
StringEncoder 功能StringEncoder是一个字符编码器它将字符串String数据转换为字节数组byte[]。用途在网络通信中数据传输是以字节流的形式进行的因此当需要发送文本数据时需要将字符串转换为字节。StringEncoder就是执行这种转换的组件。工作方式它使用指定的字符集如UTF-8将字符串编码为字节。 StringDecoder 功能StringDecoder是一个字符解码器它将接收到的字节数组byte[]数据转换为字符串String。用途当服务器或客户端接收到字节流数据时需要将这些字节解码为文本格式以便进行进一步处理。StringDecoder就是用来完成这个任务的。工作方式它使用指定的字符集如UTF-8将字节解码为字符串。 Netty 中的 StringEncoder 和 StringDecoder 是专门用于处理字符串数据的编码和解码器。这两个组件可以简化字符串在网络中的传输过程让开发者能够更加方便地处理文本数据。
StringEncoder
StringEncoder 是一个将字符串编码为字节流的组件。在 Netty 的 pipeline 中当你需要将字符串发送到网络时你可以使用 StringEncoder 来实现。它会将字符串转换为字节流以便可以在网络中传输。 例如当你使用 Netty 的 Bootstrap 类来配置你的客户端时你可以为你的 channel pipeline 添加一个 StringEncoder
Bootstrap bootstrap new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializerSocketChannel() {Overridepublic void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new StringEncoder());// 添加其他 handlers...}});在这个例子中StringEncoder 被添加到了 channel 的 pipeline 中这样在数据传输过程中发送的字符串就会被自动编码为字节流。 StringDecoder
与 StringEncoder 相对应StringDecoder 是用于将接收到的字节流解码为字符串的组件。当你在 Netty 的 pipeline 中接收到字节流时你可以使用 StringDecoder 来自动将字节流转换为字符串。
继续上面的例子如果你想在 pipeline 中添加 StringDecoder你可以这样做
Bootstrap bootstrap new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializerSocketChannel() {Overridepublic void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new StringDecoder());// 添加其他 handlers...}});在这个例子中StringDecoder 被添加到了 channel 的 pipeline 中这样在数据接收过程中接收到的字节流就会被自动解码为字符串。 总的来说StringEncoder 和 StringDecoder 是 Netty 中专门用于处理字符串数据的编码和解码器它们简化了字符串在网络中的传输过程让开发者能够更加方便地处理文本数据。 Code package com.artisan.codec.stringencoder;import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;/*** author 小工匠* version 1.0* mark: show me the code , change the world*/
public class NettyServer {// Netty服务器的主方法public static void main(String[] args) throws Exception {// 创建boss线程组用于接受客户端连接EventLoopGroup bossGroup new NioEventLoopGroup(1);// 创建worker线程组用于进行SocketChannel的数据读写EventLoopGroup workerGroup new NioEventLoopGroup();try {// 创建ServerBootstrap它是Netty服务端的启动助手ServerBootstrap serverBootstrap new ServerBootstrap();// 绑定线程组到ServerBootstrapserverBootstrap.group(bossGroup, workerGroup)// 指定使用NioServerSocketChannel接受进来的连接.channel(NioServerSocketChannel.class)// 设置子通道处理器.childHandler(new ChannelInitializerSocketChannel() {Overrideprotected void initChannel(SocketChannel ch) throws Exception {// 获取通道的管道ChannelPipeline pipeline ch.pipeline();// 添加字符串解码器pipeline.addLast(new StringDecoder());// 添加自定义的处理器pipeline.addLast(new NettyServerHandler());}});// 打印服务启动信息System.out.println(netty server start。。);// 绑定端口号并同步等待成功即启动服务端ChannelFuture channelFuture serverBootstrap.bind(1234).sync();// 等待服务器socket关闭channelFuture.channel().closeFuture().sync();} finally {// 优雅地关闭boss线程组bossGroup.shutdownGracefully();// 优雅地关闭worker线程组workerGroup.shutdownGracefully();}}
}
package com.artisan.codec.stringencoder;import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
/*** author 小工匠* version 1.0* mark: show me the code , change the world*/
public class NettyServerHandler extends ChannelInboundHandlerAdapter {Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {System.out.println(从客户端读取到String msg.toString());}Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();ctx.close();}
}
这段代码是一个简单的Netty服务器启动类其中包括了启动Netty服务器的所有必要步骤。代码中包含了中文注释对每一部分的功能都做了简单解释。 package com.artisan.codec.stringencoder;import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
/*** author 小工匠* version 1.0* mark: show me the code , change the world*/
public class NettyServerHandler extends ChannelInboundHandlerAdapter {// 当读取到客户端发送的消息时会调用此方法Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {// 打印从客户端读取到的字符串消息System.out.println(从客户端读取到String msg.toString());}// 当发生异常时会调用此方法Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {// 打印异常堆栈信息cause.printStackTrace();// 关闭通道ctx.close();}
} package com.artisan.codec.stringencoder;import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;/*** author 小工匠* version 1.0* mark: show me the code , change the world*/
public class NettyClient {// Netty客户端的主方法public static void main(String[] args) throws Exception {// 创建事件循环组EventLoopGroup group new NioEventLoopGroup();try {// 创建Bootstrap它是Netty客户端的启动助手Bootstrap bootstrap new Bootstrap();// 绑定事件循环组到Bootstrapbootstrap.group(group).channel(NioSocketChannel.class)// 设置通道初始化处理器.handler(new ChannelInitializerSocketChannel() {Overrideprotected void initChannel(SocketChannel ch) throws Exception {// 获取通道的管道ChannelPipeline pipeline ch.pipeline();// 添加字符串编码器pipeline.addLast(new StringEncoder());// 添加自定义的处理器pipeline.addLast(new NettyClientHandler());}});// 打印客户端启动信息System.out.println(netty client start。。);// 连接到服务器同步等待成功即启动客户端ChannelFuture channelFuture bootstrap.connect(127.0.0.1, 1234).sync();// 等待客户端socket关闭channelFuture.channel().closeFuture().sync();} finally {// 优雅地关闭事件循环组group.shutdownGracefully();}}
}
这段代码是一个简单的Netty客户端启动类其中包括了启动Netty客户端的所有必要步骤。代码中包含了中文注释对每一部分的功能都做了简单解释。
package com.artisan.codec.stringencoder;import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;/*** author 小工匠* version 1.0* mark: show me the code , change the world*/
public class NettyClientHandler extends ChannelInboundHandlerAdapter {// 当从服务器接收到消息时会调用此方法Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {// 打印接收到的服务器消息System.out.println(收到服务器消息 msg);}// 当通道激活时会调用此方法Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {// 定义要发送的字符串消息String msg 字符串消息;// 打印发送消息的日志信息System.out.println(NettyClientHandler发送数据 msg);// 向服务器发送消息ctx.writeAndFlush(msg);}
}
这段代码是一个自定义的Netty客户端处理器继承自ChannelInboundHandlerAdapter。其中包括了两个重写的方法channelRead和channelActive分别用于处理服务器消息的读取和通道激活时发送消息。代码中包含了中文注释对每一部分的功能都做了简单解释 【测试结果】 源码分析 StringEncoder
// StringEncoder类继承自MessageToMessageEncoder用于将字符序列CharSequence消息转换为另一个消息类型
Sharable
public class StringEncoder extends MessageToMessageEncoderCharSequence {// 用于编码的字符集private final Charset charset;/*** 使用当前系统的默认字符集创建一个新的实例。*/public StringEncoder() {this(Charset.defaultCharset());}/*** 使用指定的字符集创建一个新的实例。*/public StringEncoder(Charset charset) {this.charset ObjectUtil.checkNotNull(charset, charset);}// 重写父类的encode方法实现字符序列到字节的转换Overrideprotected void encode(ChannelHandlerContext ctx, CharSequence msg, ListObject out) throws Exception {// 如果字符序列为空则直接返回if (msg.length() 0) {return;}// 使用ByteBufUtil.encodeString方法将字符序列编码为字节并使用ctx.alloc()分配内存缓冲区// 然后将编码后的字节添加到输出列表out中以便后续处理out.add(ByteBufUtil.encodeString(ctx.alloc(), CharBuffer.wrap(msg), charset));}
} 类继承关系 StringEncoder继承自MessageToMessageEncoderCharSequence后者又继承自ChannelOutboundHandlerAdapter。MessageToMessageEncoder接口用于将消息对象转换为另一个消息对象而这里的参数CharSequence表示输入的消息对象类型即字符序列。 构造函数 StringEncoder()默认构造函数使用默认字符集UTF-8。StringEncoder(Charset charset)指定字符集的构造函数。这里使用了ObjectUtil.checkNotNull方法来检查字符集是否为空保证字符集的有效性。 核心方法 encode(ChannelHandlerContext ctx, CharSequence msg, ListObject out)将字符序列消息编码为字节。这个方法重写了MessageToMessageEncoder接口的encode方法。在编码过程中首先检查字符序列是否为空如果为空则直接返回。使用ByteBufUtil.encodeString方法将字符序列编码为字节并使用ctx.alloc()分配内存缓冲区。将编码后的字节添加到输出列表out中以便后续处理。 异常处理 在encode方法中如果发生异常会抛出异常。 通过以上分析我们可以看出StringEncoder的主要作用是将字符序列消息编码为字节。它利用指定的字符集进行编码并在异常情况下抛出异常。这段代码简洁明了实现了字符串编码的核心功能。 StringDecoder
/*** 字符串解码器继承自Netty的MessageToMessageDecoder用于将ByteBuf消息解码为字符串消息。*/
Sharable
public class StringDecoder extends MessageToMessageDecoderByteBuf {// 字符集解码器用于解码ByteBuf中的数据为字符串private final Charset charset;/*** 使用默认的系统字符集创建一个新的解码器实例。*/public StringDecoder() {this(Charset.defaultCharset());}/*** 使用指定的字符集创建一个新的解码器实例。*/public StringDecoder(Charset charset) {this.charset ObjectUtil.checkNotNull(charset, charset);}/*** 重写decode方法将ByteBuf中的数据解码为字符串并添加到解码消息列表中。*/Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf msg, ListObject out) throws Exception {// 将ByteBuf转换为字符串并使用指定的字符集解码out.add(msg.toString(charset));}
}
StringDecoder是Netty网络通信框架中的一个解码器用于将接收到的字节缓冲区ByteBuf解码为字符串。下面是对StringDecoder源码的分析
类定义StringDecoder继承自MessageToMessageDecoder并实现了Sharable接口。Sharable接口主要用于实现解码器的共享表示同一个解码器实例可以在不同的ChannelHandlerContext中使用。
Sharable
public class StringDecoder extends MessageToMessageDecoderByteBuf {字段定义StringDecoder类中有一个私有字段charset它表示用于解码的字符集。
private final Charset charset;构造函数StringDecoder类有两个构造函数一个是无参构造函数另一个是带有字符集参数的构造函数。无参构造函数会使用系统默认的字符集创建解码器实例而有参构造函数允许用户指定字符集。
public StringDecoder() {this(Charset.defaultCharset());
}
public StringDecoder(Charset charset) {this.charset ObjectUtil.checkNotNull(charset, charset);
}decode方法decode方法是MessageToMessageDecoder类的一个抽象方法用于实现具体的解码逻辑。在StringDecoder中它将接收到的字节缓冲区ByteBuf转换为字符串并使用指定的字符集进行解码。最后将解码后的字符串添加到解码消息列表中。
Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, ListObject out) throws Exception {out.add(msg.toString(charset));
}总结StringDecoder是Netty中的一个解码器用于将接收到的字节缓冲区ByteBuf解码为字符串。它提供了两个构造函数允许用户指定字符集。在decode方法中它将ByteBuf转换为字符串并使用指定的字符集进行解码将解码后的字符串添加到解码消息列表中。 小结
在Netty的通道处理器ChannelHandler中StringEncoder和StringDecoder通常以管道Pipeline的形式添加到通道Channel中这样在数据传输过程中发送的数据会被StringEncoder编码接收的数据会被StringDecoder解码。通过这种方式Netty保证了字符串数据在网络中的高效传输和正确解析。
简而言之StringEncoder和StringDecoder是Netty中处理字符串数据编解码的关键组件它们让字符串数据可以在网络中安全、准确地传输。