1、netty的编码和解码,在数据传输的时候,考虑数据安全,数据完整性都是很有必要的。这里主要是介绍netty3和netty5的编解码方式。其实从StringEncoder和StringDecoder中也可以获取源码的编解码规则。然后改变成自己的编解码规则也是可以的。

  2、netty3和netty5的编解码方式还是存在一定差别的。个人感觉netty5来的更加实用和方便。

  3、netty3的编解码规则

  1)数据编码规则(我这里只是用于显示,数据规则很简单)

  包头+模块+数据(请求编解码)

  包头+模块+状态+数据(响应编解码)

  2)目录

  

  3)请求和相应对象

package com.troy.data.domain;

//请求数据
public class Request { //模块类型
private int model;
//数据
private byte[] data; public int getModel() {
return model;
} public void setModel(int model) {
this.model = model;
} public byte[] getData() {
return data;
} public void setData(byte[] data) {
this.data = data;
} @Override
public String toString() {
return "Request{" +
"model=" + model +
", data=" + new String(data) +
'}';
}
}
package com.troy.data.domain;

import java.util.Arrays;

//响应数据
public class Response { //模块类型
private int model;
//状态码
private int status;
//数据
private byte[] data; public int getModel() {
return model;
} public void setModel(int model) {
this.model = model;
} public int getStatus() {
return status;
} public void setStatus(int status) {
this.status = status;
} public byte[] getData() {
return data;
} public void setData(byte[] data) {
this.data = data;
} @Override
public String toString() {
return "Response{" +
"model=" + model +
", status=" + status +
", data=" + new String(data) +
'}';
}
}

  4)常量(这里的包头,因为是固定的就写了一个常量)

package com.troy.data.constant;

//常量
public class ConsantUtil { //固定常量用于数据拼接,确认
public static final int PACKAGE_HEADER = -; }

  5)请求编解码

package com.troy.data.codec;

import com.troy.data.constant.ConsantUtil;
import com.troy.data.domain.Request;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; public class RequestEncode extends OneToOneEncoder { protected Object encode(ChannelHandlerContext channelHandlerContext, Channel channel, Object o) throws Exception { Request request = (Request) o;
ChannelBuffer channelBuffer = ChannelBuffers.dynamicBuffer();
channelBuffer.writeInt(ConsantUtil.PACKAGE_HEADER);
channelBuffer.writeInt(ConsantUtil.PACKAGE_HEADER);
channelBuffer.writeBytes(request.getData());
return channelBuffer;
}
}
package com.troy.data.codec;

import com.troy.data.constant.ConsantUtil;
import com.troy.data.domain.Request;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; //请求数据解码
public class RequestDecode extends OneToOneDecoder { protected Object decode(ChannelHandlerContext channelHandlerContext, Channel channel, Object o) throws Exception {
ChannelBuffer channelBuffer = (ChannelBuffer) o;
if (ConsantUtil.PACKAGE_HEADER == channelBuffer.readInt()) {
Request request = new Request();
request.setModel(channelBuffer.readInt());
byte[] bytes = new byte[channelBuffer.readableBytes()];
channelBuffer.readBytes(bytes);
request.setData(bytes);
return request;
}
return null;
}
}

  6)响应编解码

package com.troy.data.codec;

import com.troy.data.constant.ConsantUtil;
import com.troy.data.domain.Response;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; //响应编码器
public class ResponseEncode extends OneToOneEncoder { protected Object encode(ChannelHandlerContext channelHandlerContext, Channel channel, Object o) throws Exception {
Response response = (Response) o;
ChannelBuffer channelBuffer = ChannelBuffers.dynamicBuffer();
channelBuffer.writeInt(ConsantUtil.PACKAGE_HEADER);
channelBuffer.writeInt(response.getModel());
channelBuffer.writeInt(response.getStatus());
channelBuffer.writeBytes(response.getData());
return channelBuffer;
}
}
package com.troy.data.codec;

import com.troy.data.constant.ConsantUtil;
import com.troy.data.domain.Response;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; //响应解码
public class ResponseDecode extends OneToOneDecoder{ protected Object decode(ChannelHandlerContext channelHandlerContext, Channel channel, Object o) throws Exception {
ChannelBuffer channelBuffer = (ChannelBuffer) o;
if (ConsantUtil.PACKAGE_HEADER == channelBuffer.readInt()) {
Response response = new Response();
response.setModel(channelBuffer.readInt());
response.setStatus(channelBuffer.readInt());
byte[] bytes = new byte[channelBuffer.readableBytes()];
channelBuffer.readBytes(bytes);
response.setData(bytes);
return response;
}
return null;
}
}

  7)设置对应的管道编解码就可以了

  a、客户端

     //设置管道工厂
clientBootstrap.setPipelineFactory(new ChannelPipelineFactory() { public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline channelPipeline = Channels.pipeline();
channelPipeline.addLast("decode",new RequestEncode());
channelPipeline.addLast("encode",new ResponseDecode());
channelPipeline.addLast("client",new ClientHandler());
return channelPipeline;
}
});
  @Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
Response response = (Response) e.getMessage();
System.out.println(response.toString());
super.messageReceived(ctx, e);
}

  b、服务端

        //设置管道流
serverBootstrap.setPipelineFactory(new ChannelPipelineFactory() { public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline channelPipeline = Channels.pipeline();
//添加处理方式
channelPipeline.addLast("idle",new IdleStateHandler(new HashedWheelTimer(),,,));
channelPipeline.addLast("decode",new RequestDecode());
channelPipeline.addLast("encode",new ResponseEncode());
channelPipeline.addLast("server",new ServerHandler());
return channelPipeline;
}
});
  @Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
Request request = (Request) e.getMessage();
System.out.println("client:"+request.toString());
Response response = new Response();
response.setModel();
response.setStatus();
response.setData("hello client".getBytes());
ctx.getChannel().write(response);
super.messageReceived(ctx, e);
}

  4、netty5的编解码规则

  1)数据结构、目录结构、对象、常量都是一样。

  2)编解码的编写方式有些不一样

  a、请求编解码

package com.troy.data.codec;

import com.troy.data.constant.ConsantUtil;
import com.troy.data.domain.Request;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder; import java.util.List;
@ChannelHandler.Sharable
public class RequestEncode extends MessageToMessageEncoder<Request> { protected void encode(ChannelHandlerContext channelHandlerContext, Request request, List<Object> list) throws Exception {
ByteBuf byteBuf = Unpooled.buffer();
byteBuf.writeInt(ConsantUtil.PACKAGE_HEADER);
byteBuf.writeInt(request.getModel());
byteBuf.writeBytes(request.getData());
list.add(byteBuf);
}
}

package com.troy.data.codec;

import com.troy.data.constant.ConsantUtil;
import com.troy.data.domain.Request;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder; import java.util.List; //请求数据解码
@ChannelHandler.Sharable
public class RequestDecode extends MessageToMessageDecoder<ByteBuf>{ protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
if (ConsantUtil.PACKAGE_HEADER == byteBuf.readInt()) {
//当数据超过指定值的时候跳过这部分数据
if (byteBuf.readableBytes() > ) {
byteBuf.skipBytes(byteBuf.readableBytes());
}
//一个字节一个字节的读取,知道读取到包头
while(true) {
byteBuf.markReaderIndex();
if (ConsantUtil.PACKAGE_HEADER == byteBuf.readInt()) {
break;
}
byteBuf.resetReaderIndex();
byteBuf.readByte();
}
Request request = new Request();
request.setModel(byteBuf.readInt());
byte[] bytes = new byte[byteBuf.readableBytes()];
byteBuf.readBytes(bytes);
request.setData(bytes);
list.add(request);
}
}
}

  b、响应编解码

package com.troy.data.codec;

import com.troy.data.constant.ConsantUtil;
import com.troy.data.domain.Response;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder; import java.util.List; //响应编码器
@ChannelHandler.Sharable
public class ResponseEncode extends MessageToMessageEncoder<Response> { protected void encode(ChannelHandlerContext channelHandlerContext, Response response, List<Object> list) throws Exception {
ByteBuf byteBuf = Unpooled.buffer();
byteBuf.writeInt(ConsantUtil.PACKAGE_HEADER);
byteBuf.writeInt(response.getModel());
byteBuf.writeInt(response.getStatus());
byteBuf.writeBytes(response.getData());
list.add(byteBuf);
}
}

package com.troy.data.codec;

import com.troy.data.constant.ConsantUtil;
import com.troy.data.domain.Response;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder; import java.util.List; //响应解码
@ChannelHandler.Sharable
public class ResponseDecode extends MessageToMessageDecoder<ByteBuf>{ protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
if (ConsantUtil.PACKAGE_HEADER == byteBuf.readInt()) {
//当数据超过指定值的时候跳过这部分数据
if (byteBuf.readableBytes() > ) {
byteBuf.skipBytes(byteBuf.readableBytes());
}
//一个字节一个字节的读取,知道读取到包头
while(true) {
byteBuf.markReaderIndex();
if (ConsantUtil.PACKAGE_HEADER == byteBuf.readInt()) {
break;
}
byteBuf.resetReaderIndex();
byteBuf.readByte();
}
Response response = new Response();
response.setModel(byteBuf.readInt());
response.setStatus(byteBuf.readInt());
byte[] bytes = new byte[byteBuf.readableBytes()];
byteBuf.readBytes(bytes);
response.setData(bytes);
list.add(response);
}
}
}

  3)处理上面基本上都是一样的。

  5、netty的编解码,主要目的就是处理通讯问题,对数据进行自定义处理!

  6、源码下载:https://pan.baidu.com/s/1nvUnmEt

netty之编解码的更多相关文章

  1. Netty入门系列(3) --使用Netty进行编解码的操作

    前言 何为编解码,通俗的来说,我们需要将一串文本信息从A发送到B并且将这段文本进行加工处理,如:A将信息文本信息编码为2进制信息进行传输.B接受到的消息是一串2进制信息,需要将其解码为文本信息才能正常 ...

  2. java架构之路-(netty专题)netty的编解码(出入战)与粘包拆包

    上次回归: 上次博客我们主要说了netty的基本使用,都是一些固定的模式去写的,我们只需要关注我们的拦截器怎么去写就可以了,然后我们用我们的基础示例,改造了一个简单的聊天室程序,可以看到内部加了一个S ...

  3. Netty 编解码技术 数据通信和心跳监控案例

    Netty 编解码技术 数据通信和心跳监控案例 多台服务器之间在进行跨进程服务调用时,需要使用特定的编解码技术,对需要进行网络传输的对象做编码和解码操作,以便完成远程调用.Netty提供了完善,易扩展 ...

  4. Netty 源码 ChannelHandler(四)编解码技术

    Netty 源码 ChannelHandler(四)编解码技术 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) 一.拆包与粘 ...

  5. 【转】Netty系列之Netty编解码框架分析

    http://www.infoq.com/cn/articles/netty-codec-framework-analyse/ 1. 背景 1.1. 编解码技术 通常我们也习惯将编码(Encode)称 ...

  6. Netty系列之Netty编解码框架分析

    1. 背景 1.1. 编解码技术 通常我们也习惯将编码(Encode)称为序列化(serialization),它将对象序列化为字节数组,用于网络传输.数据持久化或者其它用途. 反之,解码(Decod ...

  7. netty源码解解析(4.0)-19 ChannelHandler: codec--常用编解码实现

    数据包编解码过程中主要的工作就是:在编码过程中进行序列化,在解码过程中从Byte流中分离出数据包然后反序列化.在MessageToByteEncoder中,已经解决了序列化之后的问题,ByteToMe ...

  8. Netty对常用编解码的支持

    参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! Netty对编解码的支持 打开Netty的源码,它对很多的编码器都提 ...

  9. Netty 编解码奥秘

    Netty中编解码 Netty 的解码器有很多种,比如基于长度的,基于分割符的,私有协议的.但是,总体的思路都是一致的. 拆包思路:当数据满足了 解码条件时,将其拆开.放到数组.然后发送到业务 han ...

随机推荐

  1. spring定时器quartz版本问题

    如果quartz的版本是1.8.5启动会报错,修改给2.0版本以上即可 <dependency> <groupId>org.quartz-scheduler</group ...

  2. ResNet 残差网络训练数据

    https://github.com/tornadomeet/ResNet 图片地址: data/trian/cifar10_cifar10.rec data/train/cifar10_val.re ...

  3. 配置git服务

    https://www.cnblogs.com/sumuncle/p/6362697.html

  4. Grunt中批量无损压缩图片插件--Grunt-contrib-imagemin

    Photoshop 切出的图片,无论是 PNG 还是 JPEG/JPG 格式,都含有许多相关信息,又或多余的颜色值,这些信息和颜色值,对网页前端并没有用处,反而增加图片大小,所以 Google Pag ...

  5. 时钟晶振32.768KHz为什么是15分频?

    实时时钟晶振为什么选择是32768Hz的晶振,在百度上搜索的话大部分的答案都是说2的15次方是32768,使用这个频率的晶振,人们可以很容易的通过分频电路得到1Hz的计时脉冲.但是话有说回来了,2的整 ...

  6. EF Core 2.1 中的 Eager loading、Explicit loading和LazyLoading (转自MSDN)

    Entity Framework Core allows you to use the navigation properties in your model to load related enti ...

  7. 常用的layer弹出层

    本文来自 松耦合 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/dunegao/article/details/78978448?utm_source=copy 常用 ...

  8. 利用python 传输文件

    最近在学python3 发现了一个很有用的功能,该功能可以将安装python 的机器作为一台http 服务器来分享本机的文件, 具体的使用记录如下 python3 的使用方法 直接在windows 的 ...

  9. Knowledge Point 20180305 详解精度问题

    1.1 精度与基本数据类型运算的深度解析 我们在探讨Java基本数据类型时多次提到过精度的问题,那么计算机中的精度究竟是什么样的,为什么我们有时候的计算和我们预期的不同呢?下面我们通过精度来了解: 1 ...

  10. 【POJ 3368】Frequent values(RMQ)

    Description You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In ad ...