架构师养成记--21.netty编码解码
背景
作为网络传输框架,免不了哟啊传输对象,对象在传输之前就要序列化,这个序列化的过程就是编码过程。接收到编码后的数据就需要解码,还原传输的数据。
代码
工厂类
- import io.netty.handler.codec.marshalling.DefaultMarshallerProvider;
- import io.netty.handler.codec.marshalling.DefaultUnmarshallerProvider;
- import io.netty.handler.codec.marshalling.MarshallerProvider;
- import io.netty.handler.codec.marshalling.MarshallingDecoder;
- import io.netty.handler.codec.marshalling.MarshallingEncoder;
- import io.netty.handler.codec.marshalling.UnmarshallerProvider;
- import org.jboss.marshalling.MarshallerFactory;
- import org.jboss.marshalling.Marshalling;
- import org.jboss.marshalling.MarshallingConfiguration;
- /**
- * Marshalling工厂
- * @author(alienware)
- * @since 2014-12-16
- */
- public final class MarshallingCodeCFactory {
- /**
- * 创建Jboss Marshalling解码器MarshallingDecoder
- * @return MarshallingDecoder
- */
- public static MarshallingDecoder buildMarshallingDecoder() {
- //首先通过Marshalling工具类的精通方法获取Marshalling实例对象 参数serial标识创建的是java序列化工厂对象。
- final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
- //创建了MarshallingConfiguration对象,配置了版本号为5
- final MarshallingConfiguration configuration = new MarshallingConfiguration();
- configuration.setVersion(5);
- //根据marshallerFactory和configuration创建provider
- UnmarshallerProvider provider = new DefaultUnmarshallerProvider(marshallerFactory, configuration);
- //构建Netty的MarshallingDecoder对象,俩个参数分别为provider和单个消息序列化后的最大长度
- MarshallingDecoder decoder = new MarshallingDecoder(provider, 1024 * 1024 * 1);
- return decoder;
- }
- /**
- * 创建Jboss Marshalling编码器MarshallingEncoder
- * @return MarshallingEncoder
- */
- public static MarshallingEncoder buildMarshallingEncoder() {
- final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
- final MarshallingConfiguration configuration = new MarshallingConfiguration();
- configuration.setVersion(5);
- MarshallerProvider provider = new DefaultMarshallerProvider(marshallerFactory, configuration);
- //构建Netty的MarshallingEncoder对象,MarshallingEncoder用于实现序列化接口的POJO对象序列化为二进制数组
- MarshallingEncoder encoder = new MarshallingEncoder(provider);
- return encoder;
- }
- }
服务器端
- import io.netty.bootstrap.ServerBootstrap;
- import io.netty.channel.ChannelFuture;
- import io.netty.channel.ChannelInitializer;
- import io.netty.channel.ChannelOption;
- 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.logging.LogLevel;
- import io.netty.handler.logging.LoggingHandler;
- public class Server {
- public static void main(String[] args) throws Exception{
- EventLoopGroup pGroup = new NioEventLoopGroup();
- EventLoopGroup cGroup = new NioEventLoopGroup();
- ServerBootstrap b = new ServerBootstrap();
- b.group(pGroup, cGroup)
- .channel(NioServerSocketChannel.class)
- .option(ChannelOption.SO_BACKLOG, 1024)
- //设置日志
- .handler(new LoggingHandler(LogLevel.INFO))
- .childHandler(new ChannelInitializer<SocketChannel>() {
- protected void initChannel(SocketChannel sc) throws Exception {
- sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
- sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
- sc.pipeline().addLast(new ServerHandler());
- }
- });
- ChannelFuture cf = b.bind(8765).sync();
- cf.channel().closeFuture().sync();
- pGroup.shutdownGracefully();
- cGroup.shutdownGracefully();
- }
- }
- import io.netty.channel.ChannelHandlerAdapter;
- import io.netty.channel.ChannelHandlerContext;
- import java.io.File;
- import java.io.FileOutputStream;
- import bhz.utils.GzipUtils;
- public class ServerHandler extends ChannelHandlerAdapter{
- @Override
- public void channelActive(ChannelHandlerContext ctx) throws Exception {
- }
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
- Req req = (Req)msg;
- System.out.println("Server : " + req.getId() + ", " + req.getName() + ", " + req.getRequestMessage());
- byte[] attachment = GzipUtils.ungzip(req.getAttachment());
- String path = System.getProperty("user.dir") + File.separatorChar + "receive" + File.separatorChar + "001.jpg";
- FileOutputStream fos = new FileOutputStream(path);
- fos.write(attachment);
- fos.close();
- Resp resp = new Resp();
- resp.setId(req.getId());
- resp.setName("resp" + req.getId());
- resp.setResponseMessage("响应内容" + req.getId());
- ctx.writeAndFlush(resp);//.addListener(ChannelFutureListener.CLOSE);
- }
- @Override
- public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
- }
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
- ctx.close();
- }
- }
客户端
- import io.netty.bootstrap.Bootstrap;
- import io.netty.channel.ChannelFuture;
- 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.NioSocketChannel;
- import java.io.File;
- import java.io.FileInputStream;
- import bhz.utils.GzipUtils;
- public class Client {
- public static void main(String[] args) throws Exception{
- EventLoopGroup group = new NioEventLoopGroup();
- Bootstrap b = new Bootstrap();
- b.group(group)
- .channel(NioSocketChannel.class)
- .handler(new ChannelInitializer<SocketChannel>() {
- @Override
- protected void initChannel(SocketChannel sc) throws Exception {
- sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
- sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
- sc.pipeline().addLast(new ClientHandler());
- }
- });
- ChannelFuture cf = b.connect("127.0.0.1", 8765).sync();
- for(int i = 0; i < 5; i++ ){
- Req req = new Req();
- req.setId("" + i);
- req.setName("pro" + i);
- req.setRequestMessage("数据信息" + i);
- String path = System.getProperty("user.dir") + File.separatorChar + "sources" + File.separatorChar + "001.jpg";
- File file = new File(path);
- FileInputStream in = new FileInputStream(file);
- byte[] data = new byte[in.available()];
- in.read(data);
- in.close();
- req.setAttachment(GzipUtils.gzip(data));
- cf.channel().writeAndFlush(req);
- }
- cf.channel().closeFuture().sync();
- group.shutdownGracefully();
- }
- }
- import io.netty.channel.ChannelHandlerAdapter;
- import io.netty.channel.ChannelHandlerContext;
- import io.netty.util.ReferenceCountUtil;
- public class ClientHandler extends ChannelHandlerAdapter{
- @Override
- public void channelActive(ChannelHandlerContext ctx) throws Exception {
- }
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
- try {
- Resp resp = (Resp)msg;
- System.out.println("Client : " + resp.getId() + ", " + resp.getName() + ", " + resp.getResponseMessage());
- } finally {
- ReferenceCountUtil.release(msg);
- }
- }
- @Override
- public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
- }
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
- ctx.close();
- }
- }
工具类(压缩文件)
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.util.zip.GZIPInputStream;
- import java.util.zip.GZIPOutputStream;
- public class GzipUtils {
- public static byte[] gzip(byte[] data) throws Exception{
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- GZIPOutputStream gzip = new GZIPOutputStream(bos);
- gzip.write(data);
- gzip.finish();
- gzip.close();
- byte[] ret = bos.toByteArray();
- bos.close();
- return ret;
- }
- public static byte[] ungzip(byte[] data) throws Exception{
- ByteArrayInputStream bis = new ByteArrayInputStream(data);
- GZIPInputStream gzip = new GZIPInputStream(bis);
- byte[] buf = new byte[1024];
- int num = -1;
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- while((num = gzip.read(buf, 0 , buf.length)) != -1 ){
- bos.write(buf, 0, num);
- }
- gzip.close();
- bis.close();
- byte[] ret = bos.toByteArray();
- bos.flush();
- bos.close();
- return ret;
- }
- public static void main(String[] args) throws Exception{
- //读取文件
- String readPath = System.getProperty("user.dir") + File.separatorChar + "sources" + File.separatorChar + "006.jpg";
- File file = new File(readPath);
- FileInputStream in = new FileInputStream(file);
- byte[] data = new byte[in.available()];
- in.read(data);
- in.close();
- System.out.println("文件原始大小:" + data.length);
- //测试压缩
- byte[] ret1 = GzipUtils.gzip(data);
- System.out.println("压缩之后大小:" + ret1.length);
- byte[] ret2 = GzipUtils.ungzip(ret1);
- System.out.println("还原之后大小:" + ret2.length);
- //写出文件
- String writePath = System.getProperty("user.dir") + File.separatorChar + "receive" + File.separatorChar + "006.jpg";
- FileOutputStream fos = new FileOutputStream(writePath);
- fos.write(ret2);
- fos.close();
- }
- }
数据对象
- import java.io.Serializable;
- public class Req implements Serializable{
- private static final long SerialVersionUID = 1L;
- private String id ;
- private String name ;
- private String requestMessage ;
- private byte[] attachment;
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getRequestMessage() {
- return requestMessage;
- }
- public void setRequestMessage(String requestMessage) {
- this.requestMessage = requestMessage;
- }
- public byte[] getAttachment() {
- return attachment;
- }
- public void setAttachment(byte[] attachment) {
- this.attachment = attachment;
- }
- }
- import java.io.Serializable;
- public class Resp implements Serializable{
- private static final long serialVersionUID = 1L;
- private String id;
- private String name;
- private String responseMessage;
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getResponseMessage() {
- return responseMessage;
- }
- public void setResponseMessage(String responseMessage) {
- this.responseMessage = responseMessage;
- }
- }
架构师养成记--21.netty编码解码的更多相关文章
- 架构师养成记--20.netty的tcp拆包粘包问题
问题描述 比如要发ABC DEFG HIJK 这一串数据,其中ABC是一个包,DEFG是一个包,HIJK是一个包.由于TCP是基于流发送的,所以有可能出现ABCD EFGH 这种情况,那么ABC和D就 ...
- 架构师养成记--19.netty
一.Netty初步 为什么选择Netty? 和NIO比较,要实现一个通信要简单得很多,性能很好.分布式消息中间件.storm.Dubble都是使用Netty作为底层通信. Netty5.0要求jdk1 ...
- 架构师养成记--22.客户端与服务器端保持连接的解决方案,netty的ReadTimeoutHandler
概述 保持客户端与服务器端连接的方案常用的有3种 1.长连接,也就是客户端与服务器端一直保持连接,适用于客户端比较少的情况. 2.定时段连接,比如在某一天的凌晨建立连接,适用于对实时性要求不高的情况. ...
- 架构师养成记--3.synchronized细节问题
一.synchronized有锁重入的特点,某个线程得到对象的锁后,再次请求此对象可以再次得到改对象的锁.如下示例,在method1中调用method2,在method2中调用method3,而met ...
- 架构师养成记--35.redis集群搭建
前记:redis哨兵经验之谈.哨兵做主从切换可能要花费一两秒,这一两秒可能会丢失很多数据.解决方法之一是在java代码中做控制,try catch 到 链接断开的异常就sleep 一两秒钟再conti ...
- 架构师养成记--15.Disruptor并发框架
一.概述 disruptor对于处理并发任务很擅长,曾有人测过,一个线程里1s内可以处理六百万个订单,性能相当感人. 这个框架的结构大概是:数据生产端 --> 缓存 --> 消费端 缓存中 ...
- 架构师养成记--14.重入锁ReentrantLock 和 读写锁 ReentrantReadWriteLock
ReentrantLock 有嗅探锁定和多路分支等功能,其实就是synchronized,wait,notify的升级. this锁定当前对象不方便,于是就有了用new Object()来作为锁的解决 ...
- 架构师养成记--12.Concurrent工具类CyclicBarrier和CountDownLatch
java.util.concurrent.CyclicBarrier 一组线程共同等待,直到达到一个公共屏障点. 举个栗子,百米赛跑中,所有运动员都要等其他运动员都准备好后才能一起跑(假如没有发令员) ...
- 架构师养成记--11.Executor概述
常用方法 Executors.newFiexdPool(int nThreads);固定线程数量的线程池: Executors.newSingleThreadExecutor();单个线程的线程池: ...
随机推荐
- 自己动手搭建Git服务器-Gitblit
首先到官网http://gitblit.com/下载最新版本的Gitblit GO 解压缩到本地目录中 E:\git\gitblit132 官方文档:http://gitblit.com/setu ...
- Linux汇编与C互相调用
一.简介 C语言调用汇编有两种方式:1.通过内嵌汇编 2.通过编译链接. 二.基础知识 对于C和汇编语言的接口主要有两个问题需要解决 1.调用者与被调用者的参数传递 正常的,定义一个函数总是希望它完 ...
- [Training Video - 4] [Groovy] String Functions
def x="I like to read books before bed" def temp = x.split(" ") log.info "S ...
- spring mvc 数据回显
1.spring mvc自动将传入的pojo数据存入request域 request中的key是该pojo类名,首字母小写. JSP controller 第一次访问user.jsp 填写表单 点击提 ...
- 团体程序设计天梯赛L1-017 到底有多二 2017-03-22 17:31 155人阅读 评论(0) 收藏
L1-017. 到底有多二 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 一个整数"犯二的程度"定义为该数 ...
- C++ 的Tool工具收集
C++ 的Tool工具收集 1. muparser - Fast Math Parser Library 数学公式解析函数,开源工具库 网址: http://muparser.beltoforion. ...
- shell 脚本 随机抽取班上学生
#!/bin/bash # jw=('王浩' '谢云生' '黄科杨' '何星宇' '张宸兵' '邓培林' '刘桃' '杨沛东' '楚齐文' '咸鱼' '杨东' '>黄庭辉' '郑少文' '师靖' ...
- Mirth Connect的简单使用
第一步: 切换到Channels界面,右键点击New Channel 第二步 : 上面是设置一些通道信息. 其中summary(概要) 界面主要包含 通道名称,数据类型,依赖,通道初始状态,附件(是否 ...
- Homework 4
Homework 4 开发工具:dev c++ 开发语言:c++ 源代码上传至github:上传一直失败... 合作人:曹权 博客地址:http://www.cnblogs.com/c2016/ 这里 ...
- linux inode cheat sheet
sector:扇区,硬盘存储的最小单位,大小为0.5KB(512字节) block:块文件存取的最小单位,1 block=8 sector,大小4KB inode:存储文件元信息.内容包括 * 文件的 ...