java netty之decoder与encoder的使用

Netty之Decoder详解与实战 在Netty中,Decoder是一种特殊类型的ChannelHandler,用于将接收到的字节数据转换(解码)为应用程序可识别的格式。这是一个非常重要的步骤,因为网络上的数据传输通常以字节流的形式进行,而应用程序则需要这些数据转换为特定的数据结构或对象来进行进一步的处理。虽然Netty提供了多种现成的解码器,但有时您可能需要实现自定义解码器以支持特定的数据格式或协议。要实现自定义解码器,您需要继承类并实现其decode方法。@Override// 检查是否有足够的字节用于解码return; 阅读详情

在前面的文章中,对netty的使用都是基于byte类型的,但是在实际情况,直接处理byte数据是很少的,一般都是将这些数据转换成自己定义的一些类型。

也就是说在实际情况下decoder与encoder都是用到比较多的handler类型,想要了解他们是怎么实现的,我觉得首先应该知道他们是怎么使用的,那么就用官方说明的UnixTime作为例子来简单的说民一下decoder与encoder是怎么使用的吧。。。


首先先来看看client端的代码吧,由于代码比较少,这里代码就没有弄注释了,反正也比较的简单,一看就能明白是什么意思,另外没有分好几个类来写,直接在一个类中使用内部类来实现了,这样免得麻烦。。好吧,看代码:

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.MessageBuf;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundMessageHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.ByteToMessageDecoder;

public class Client {
	
	public void run() throws InterruptedException {
		EventLoopGroup worker = new NioEventLoopGroup();
		try {
			Bootstrap b = new Bootstrap();
			b.group(worker);
			b.channel(NioSocketChannel.class);
			b.handler(new ChannelInitializer<NioSocketChannel>(){

				@Override
				protected void initChannel(NioSocketChannel ch)
						throws Exception {
					// TODO Auto-generated method stub
					ch.pipeline().addLast(new TimeDecoder(), new ClientHandler());
				}
				
			});
			ChannelFuture f = b.connect("127.0.0.1", 80).sync();
			f.channel().closeFuture().sync();
		} finally {
			worker.shutdownGracefully();
		}
	}
	
	public final class TimeDecoder extends ByteToMessageDecoder{

		@Override
		protected void decode(ChannelHandlerContext ctx, ByteBuf in,
				MessageBuf<Object> out) throws Exception {
			// TODO Auto-generated method stub
			while (in.readableBytes() >= 4) {
				out.add(new UnixTime(in.readInt()));
			}
		}
		
	}
	
	public final class ClientHandler extends ChannelInboundMessageHandlerAdapter{

		@Override
		public void messageReceived(ChannelHandlerContext ctx, Object msg)
				throws Exception {
			// TODO Auto-generated method stub
			UnixTime time = (UnixTime)msg;
			System.out.println(time);
		}
		
	}
	
	public static void main(String args[]) throws InterruptedException {
		new Client().run();
	}
}

首先从类型的定义看起吧,TimeDecoder类型直接继承自ByteToMessageDecoder类型,这里需要自己实现decode方法,说白了就是将读进来的字节类型转化为定义的java类型对象。。。

然后才是真正处理读进来的数据的handler,ClientHnadler,它继承自ChannelInboundMessageHandlerAdapter,需要自己实现messageReceived方法,其实这里传进来的msg对象就是刚刚通过读进来的byte数据生成的。。。

好了两个handler的定义就差不多了,这里需要注意的代码:

ch.pipeline().addLast(new TimeDecoder(), new ClientHandler());
在初始化函数中,为当前的pipeline添加了刚刚说明的两个handler,由于调用的是addLast函数,所以这两个handler的次序如下图:


当然这里对pipeline的描述还是不够正确,因为在最前面和最后面还分别有一个默认的handler。。就不细说了。。

我们在前面的文章中有提到对于读取数据的事件,netty会从pipeline的前面向后寻找相应的inboundhandler来处理,因此我们可以知道这里handler的调用顺序就是先是decoder然后才是ClientHandler。。。其实基本上也都知道decoder是怎么实现的了,,,因为前面的分析可以知道netty的pipeline上面,handler可以访问别的handler的context的buffer。。。至于具体是怎么实现的,就留给接下来的文章吧。。。


好了,接下来来看Server部分的代码:

import newfjs.UnixTime;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundByteHandlerAdapter;
import io.netty.channel.ChannelInitializer;
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.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.MessageToByteEncoder;

public class Server {
	
	
	
	public void run() throws InterruptedException {
		EventLoopGroup boss = new NioEventLoopGroup();
		EventLoopGroup worker = new NioEventLoopGroup();
		
		try {
			ServerBootstrap b = new ServerBootstrap();
			b.group(boss, worker);
			b.channel(NioServerSocketChannel.class);   
			b.childHandler(new ChannelInitializer<NioSocketChannel>(){

				@Override
				protected void initChannel(NioSocketChannel ch)
						throws Exception {
					// TODO Auto-generated method stub
					ch.pipeline().addLast(new TimeServerHandler());
					ch.pipeline().addFirst(new TimeEncoder());
				}
				
			});
			ChannelFuture f = b.bind(80).sync();
			f.channel().closeFuture().sync();
		} finally {
			boss.shutdownGracefully();
			worker.shutdownGracefully();
		}
	}
	
	private final class TimeEncoder extends MessageToByteEncoder<UnixTime>{

		@Override
		protected void encode(ChannelHandlerContext ctx, UnixTime msg,
				ByteBuf out) throws Exception {
			// TODO Auto-generated method stub
			out.writeInt(msg.value());
		}
		
	}
	
	private final class TimeServerHandler extends ChannelInboundByteHandlerAdapter{

		@Override
	    public void channelActive(ChannelHandlerContext ctx) throws Exception {
			ctx.pipeline().write(new UnixTime());
			ctx.pipeline().write(new UnixTime());
			ctx.pipeline().write(new UnixTime());
	        ctx.pipeline().write(new UnixTime()).channel().pipeline().flush().addListener(new ChannelFutureListener(){

				@Override
				public void operationComplete(ChannelFuture future)
						throws Exception {
					// TODO Auto-generated method stub
					future.channel().pipeline().close();
				}
	        	
	        });
		}
		
		
		@Override
		protected void inboundBufferUpdated(ChannelHandlerContext ctx,
				ByteBuf in) throws Exception {
			// TODO Auto-generated method stub
			in.discardReadBytes();
		}
		
	}
	
	public static void main(String args[]) throws InterruptedException{
		new Server().run();
	}
}

在server部分定义了两个handler,其实这两个handler还分别是两种不同的类型,先来是TimeEncoder,它最终还是一个outboundhandler,也就是当调用wirte一类方法的时候会经过这个handler,这个handler用于将用户定义的数据转化成byte类型。

然后另外一个handler是TimeServerHandler,它重写了channelActive方法,也就是说当这个channel已经连接好了,那么就会调用这个方法,它直接写4个用户定义的类型。。。

至于handler初始化代码:

protected void initChannel(NioSocketChannel ch)
						throws Exception {
					// TODO Auto-generated method stub
					ch.pipeline().addLast(new TimeServerHandler());
					ch.pipeline().addFirst(new TimeEncoder());
				}
那么最后他们的样子是:


不过其实由于这两个handler是两种不同的类型,讨论他们的位置关系也没有什么意义。。但是我们通过前面的文章可以知道,当调用write方法的时候,netty会在pipeline上面从后向前的寻找outboundhandler,然后调用相应的方法,而且我们知道在pipeline的最前面还有一个默认的outboundhandler,它将会最终用于处理对外的一些操作。。其实也能猜出来encoder之后会发生什么样子的事情。。还是留个以后分析吧。。

这样,server与client就ok了,首先启动server,然后启动client,当client连接上server的时候,server就会向client发送4个自定义的time,然后再关闭当前的channel,当client接受之后,先将byte类型转化为具体的类型,然后在输出。。

以后的文章分析decoder与encoder两种handler是具体怎么实现的。。。

Java编写基于netty的RPC框架 一 简单概念 RPC: ( Remote Procedure Call),远程调用过程,是通过网络调用远程计算机的进程中某个方法,从而获取到想要的数据,过程如同调用本地的方法一样. 阻塞IO :当阻塞I/O在调用InputStream.read()方法是阻塞的,一直等到数据到来时才返回,同样ServerSocket.accept()方法时,也是阻塞,直到有客户端连接才返回,I/O通信模式如下:... 阅读详情

相关推荐

ESXI 7 :创建统信V20_1050d服务器系统虚拟机

记录一下在 X86 架构创建统信V20_1050d 虚拟机遇到的问题。已遇到的问题有①:常规服务器环境下网络连接失败重点:按照桌面版本,有问题处理简单。

guyuelin123的博客 1967

Netty内置的Decoder

1. 固定长度解码器:FixedLengthFrameDecoder 适用场景:每个接收到的数据包的长度,都是固定的。 该解码器会将入站的ByteBuf数据包拆分成一个个固定长度的数据包,然后发送给下一个入站处理器。 2. 行分割解码器:LineBaseFrameDecoder 适用场景:每个ByteBuf数据包,适用换行符作为数据包的边界分隔符 该场景下,会使用换行符把ByteBuf数据包分割成一个个完整的数据包发送到下一个入站处理器。 工作原理:遍历ByteBuf数据包中的可读字节,判断在 二进

学而不思则忘 1208

基础的pdf病毒木马

基础的pdf病毒木马 环境: 攻击机:Kali 目标操作系统:Windows 10或Windows 7 (关闭防火墙和安全软件) 目标软件:Adobe Reader 8.1.2 msf框架搜索:adobe-pdf 1.打开msfconsole 2.搜索 adobe_pdf模块 3.加载攻击模块并设置payload 4.运行生成pdf 5.将pdf拖入到win10 6.打开msf,加...

小小猪的博客 4621

Netty编码器和解码器

OverrideSystem.out.println("解码出一个整数:" + i);@OverrideSystem.out.println("打印出一个整数:" + integer);使用上面的Byte2IngeterDecoder证书解码器需要先对ByteBuf的长度进行检查,如果有足够的字节,才进行整数的读取。这种长度的判断可以由Netty的ReplayingDecoder类来完成。

qq_25046827的博客 1780

车辆TBOX科普 第7次 TBOX技术深度解析:硬件架构与核心组件详解

摘要: TBOX(车载远程信息处理单元)是智能网联汽车的核心组件,承担数据采集、通信连接与安全交互等关键功能。其硬件架构以主控单元为核心,采用ARM架构处理器(如NXP i.MX系列)实现高效能低功耗处理,搭配DDR4/LPDDR5内存保障性能,eMMC/UFS存储确保数据可靠性。设计中需平衡车规级可靠性(AEC-Q100)、EMC兼容性及成本控制,同时集成通信、定位与安全模块。未来趋势聚焦异构计算、先进制程及功能安全(ASIL-D)与信息安全融合,推动TBOX向边缘计算节点演进。该技术是汽车智能化转型的重

IT深耕十余载,大道之简 857

门控时钟(clock gating)的DFT设计

在数字IC芯片中,时钟树的功耗占比可能高达30%,因此一般会采取门控时钟的方式来降低该部分的功耗。所谓门控时钟,就是在芯片实际工作过程中,有些信号或者功能并不需要一直开启,那么就可以在它们不用的时候将其时钟信号关闭。这样一来信号不再翻转,从而能够有效减少动态功耗。 目前门控时钟都采用集成门控时钟单元(ICG,integrated clock gating cell),其结构如下。由一个latch和一个与门(也有的是或门)组成,可以过滤掉EN信号中的毛刺。一般的工艺库中都会有专门的ICG以供调用。 插入IC

weixin_44746697的博客 3872

Netty使用篇:编解码器

Netty使用篇:编解码器

七叔的博客 2万+

智能车图像处理22-进阶篇14--小s的判断

这篇文章中主要讲述智能车图像处理中 : 小s的判断方法。

taiyuezyh的博客 2565

netty系列之:netty中的自动解码器ReplayingDecoder

文章目录简介ByteToMessageDecoder可能遇到的问题ReplayingDecoder的实现原理总结 简介 netty提供了一个从ByteBuf到用户自定义的message的解码器叫做ByteToMessageDecoder,要使用这个decoder,我们需要继承这个decoder,并实现decode方法,从而在这个方法中实现ByteBuf中的内容到用户自定义message对象的转换。 那么在使用ByteToMessageDecoder的过程中会遇到什么问题呢?为什么又会有一个Replaying

程序那些事 1706

【100分】最长子字符串的长度

题目要求在一个环形字符串中找出字符 ‘o’ 出现了偶数次的最长子字符串长度。这里的字符串是一个环形的,即首尾相连。代码统计了字符串中字符 ‘o’ 的出现次数,并根据其奇偶性返回相应的最长子字符串长度。当 ‘o’ 的数量为偶数时,直接返回字符串长度;当 ‘o’ 的数量为奇数时,返回长度减去 1。给你一个字符串 s,字符串s首尾相连成一个环形 ,请你在环中找出 ‘o’ 字符出现了偶数次最长子字符串的长度。【最长子字符串的长度】

weixin_54707168的博客 895

可控异常的契约化设计:在 ABAP 中用 CX_STATIC_CHECK 把可预期错误变成接口的一部分

文章摘要: 本文探讨了ABAP系统中异常处理的工程化设计原则,强调将可预期的业务异常作为接口契约的一部分。核心观点是:对于调用方能够合理处理的错误情况,应使用继承自CX_STATIC_CHECK的受检异常,通过方法签名强制调用方处理或显式转发。文章对比了ABAP三大异常根类的适用场景,提出"三问法"判断异常是否适合受检处理,并给出了包含上下文信息的异常类实现示例。通过Fiori文件上传案例,展示了如何在分层架构中合理传递和转换异常,最终在OData服务层将业务异常映射为标准错误响应。这种

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 3060

java netty decoder与encoder的使用

在前面的文章中,对netty的使用都是基于byte类型的,但是在实际情况,直接处理byte数据是很少的,一般都是将这些数据转换成自己定义的一些类型。 也就是说在实际情况下decoder与encoder都是用到比较多的handler类型,想要了解他们是怎么实现的,我觉得首先应该知道他们是怎么使用的,那么就用官方说明的UnixTime作为例子来简单的说民一下decoder与encoder是怎么使

u010395804的专栏 6427

手把手教你学Simulink--基于光伏(PV)系统的建模与仿真场景:-不同天气条件下光伏系统的输出性能分析

本文介绍了使用Simulink和Simscape Electrical工具箱进行光伏系统建模与仿真的完整流程。内容涵盖准备工作、模型构建、仿真分析三大步骤,重点演示了如何模拟不同天气条件(光照强度、温度变化)对光伏输出性能的影响。通过添加PVArray模块、配置参数、设置环境变化条件、连接测量仪器等操作,实现了光伏系统在动态天气条件下的输出特性分析。文章还提供了仿真参数设置建议和结果分析方法,帮助用户理解环境因素与光伏性能的关联性,为光伏系统设计和优化提供参考。

MHD0815的博客 188

java encoder_java netty之decoder与encoder的使用 | 学步园

在前面的文章中,对netty的使用都是基于byte类型的,但是在实际情况,直接处理byte数据是很少的,一般都是将这些数据转换成自己定义的一些类型。也就是说在实际情况下decoder与encoder都是用到比较多的handler类型,想要了解他们是怎么实现的,我觉得首先应该知道他们是怎么使用的,那么就用官方说明的UnixTime作为例子来简单的说民一下decoder与encoder是怎么使用的吧。...

weixin_36264801的博客 600

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

java encoder序列化对象_Netty自定义Encoder/Decoder进行对象传递

转载:http://blog.youkuaiyun.com/top_code/article/details/50901623在上一篇文章中,我们使用Netty4本身自带的ObjectDecoder,ObjectEncoder来实现POJO对象的传输,但其使用的是Java内置的序列化,由于Java序列化的性能并不是很好,所以很多时候我们需要用其他高效的序列化方式,例如 protobuf,Hessian, Kr...

weixin_28832121的博客 678

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

netty 学习 (3)发送对象

Netty中,通讯的双方建立连接后,会把数据按照ByteBuf的方式进行传输,例如http协议中,就是通过HttpRequestDecoder对ByteBuf数据流进行处理,转换成http的对象。基于这个思路,我自定义一种通讯协议:Server和客户端直接传输java对象。 实现的原理是通过Encoder把java对象转换成ByteBuf流进行传输,通过Decoder把ByteBuf转换成java...

小冰的程序员之旅 1835

Netty实战练习——自定义Encoder和Decoder

目录 实现encoder和decoder的方法 一、利用netty 1、实现messageToByte,使用java原生的序列化方式 2、利用netty支持的现有序列化框架 3、自定义序列化协议 二、在handler的read和write方法中直接实现 tcp拆包粘包见下篇 需求: 1、客户端向服务端发送自定义类InputParam: public class InputPa...

weixin_43599368的博客 2506

netty codec部分剖析

netty codec

行云流水的博客 2547

8.Netty发送对象

1.Netty发送对象简介:    Netty中,通讯的双方建立连接后,会把数据按照ByteBuf的方式进行传输,例如http协议中,就是通过HttpRequestDecoder对 ByteBuf数 据流进行处理,转换成http的对象。基于这个思路,自定义一种通讯协议:Server 和 客户端直接传输 java对象   实现的原理是通过 Encoder 把 java 对象转换成 ByteB...

weixin_33882452的博客 155

Netty中对象的序列化,反序列化

之前写的nettydemmo都是传递字符串的,而在真实使用的时候我们传的都是对象,然后写序列化方法进行序列化和返序列化,在netty中对序列化和返序列化都提供了相应的接口,而且netty也支持很多的序列化方式,但这里先提供java的序列化实现方式。 一、java序列化方式 package com.decode; import java.io.ByteArrayInputStream;

bit-cafe 4688

hadoop28---netty传对象

Netty中,通讯的双方建立连接后,会把数据按照ByteBuf的方式进行传输,例如http协议中,就是通过HttpRequestDecoder对ByteBuf数据流进行处理,转换成http的对象。基于这个思路,我自定义一种通讯协议:Server和客户端直接传输java对象。 实现的原理是通过Encoder把java对象转换成ByteBuf流进行传输,通过Decoder把ByteBuf转...

weixin_30567225的博客 84

Netty学习笔记 --- Handler的执行顺序和发送对象

1、Handler Handler在netty中,无疑占据着非常重要的地位。Handler与Servlet中的filter很像,通过Handler可以完成通讯报文的解码编码、拦截指定的报文、统一对日志错误进行处理、统一对请求进行计数、控制Handler执行与否。一句话,没有它做不到的只有你想不到的。 Netty中的所有handler都实现自ChannelHandler接口。按照输入输出来分,分...

小道的博客 978

java自定义通信协议_netty 自定义通讯协议

Netty中,通讯的双方建立连接后,会把数据按照ByteBuf的方式进行传输,例如http协议中,就是通过HttpRequestDecoder对ByteBuf数据流进行处理,转换成http的对象。基于这个思路,我自定义一种通讯协议:Server和客户端直接传输java对象。实现的原理是通过Encoder把java对象转换成ByteBuf流进行传输,通过Decoder把ByteBuf转换成java对...

weixin_36444911的博客 727

Netty关键词

IO多路复用技术Java BIO阻塞式IOJava AIO异步IOJava NIO非阻塞异步IONetty  java NIO框架关键词EventLoopGroup,Encoder,Decoder,Handler===》书籍《 Netty权威指南》       ===》学习资源 http://ifeve.com/java-nio-all/       ===》TCP粘包问题及解决...

MrHelicopter的博客 290
上一篇: java netty之ChannelInboundByteHandlerAdapter
下一篇: java netty之ByteToMessageDecoder
fjs_cloud
博客等级 码龄15年 248粉丝 192原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值