博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Netty实现自定义简单的编解码器(一)
阅读量:6159 次
发布时间:2019-06-21

本文共 8892 字,大约阅读时间需要 29 分钟。

hot3.png

关于编解码器的介绍,请看我另一篇文章:

在这里实现的编解码器很简单,实现int->bytes的编码和bytes->int的解码

具体细节请看代码,注释很全面,运行结果很能说明问题

编码器

package codec.encoder;import io.netty.buffer.ByteBuf;import io.netty.channel.ChannelHandlerContext;import io.netty.handler.codec.MessageToByteEncoder;public class IntegerToByteEncoder extends MessageToByteEncoder
 {    @Override    public void encode(ChannelHandlerContext ctx, Integer msg, ByteBuf out)            throws Exception {        System.err.println("IntegerToByteEncoder encode msg is " + msg);        out.writeInt(msg);    }}

解码器

package codec.decoder;import io.netty.buffer.ByteBuf;import io.netty.channel.ChannelHandlerContext;import io.netty.handler.codec.ByteToMessageDecoder;import java.util.List;/** * 把字节转换为int * 继承抽象类ByteToMessageDecoder实现解码器 */public class ByteToIntegerDecoder extends ByteToMessageDecoder {    @Override    public void decode(ChannelHandlerContext ctx, ByteBuf in,                       List out) throws Exception {        if (in.readableBytes() >= 4) {  // Check if there are at least 4 bytes readable            int n = in.readInt();            System.err.println("ByteToIntegerDecoder decode msg is " + n);            out.add(n);      //Read integer from inbound ByteBuf, add to the List of decodec messages        }    }}

服务器端程序

package codec;import codec.decoder.ByteToIntegerDecoder;import codec.encoder.IntegerToByteEncoder;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;/** * 主要思路: * 实现了一个编码器IntegerToByteEncoder和一个解码器ByteToIntegerDecoder * 客户端直接发送一个数字 * 服务器端接收后向客户端发送一个数字 * 在这过程中可以看到解码器和编码器所起的作用 */public class HelloServer {    public void start(int port) throws Exception {        EventLoopGroup bossGroup = new NioEventLoopGroup();        EventLoopGroup workerGroup = new NioEventLoopGroup();        try {            ServerBootstrap b = new ServerBootstrap();            b.group(bossGroup, workerGroup)                    .channel(NioServerSocketChannel.class)                    .option(ChannelOption.SO_BACKLOG, 128)                    .childHandler(new ChannelInitializer
() {                        @Override                        public void initChannel(SocketChannel ch) throws Exception {                            // 注册handler                            ch.pipeline().addLast(                                    new IntegerToByteEncoder(),                                    new ByteToIntegerDecoder(),                                    new HelloServerInHandler());                        }                    });            ChannelFuture f = b.bind(port).sync();            f.channel().closeFuture().sync();        } finally {            workerGroup.shutdownGracefully();            bossGroup.shutdownGracefully();        }    }    public static void main(String[] args) throws Exception {        HelloServer server = new HelloServer();        server.start(12345);    }}
package codec;import io.netty.buffer.ByteBuf;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;// 该handler是InboundHandler类型public class HelloServerInHandler extends ChannelInboundHandlerAdapter {    @Override    public boolean isSharable() {        System.out.println("==============handler-sharable==============");        return super.isSharable();    }    @Override    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {        System.out.println("==============channel-register==============");    }    @Override    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {        System.out.println("==============channel-unregister==============");    }    @Override    public void channelActive(ChannelHandlerContext ctx) throws Exception {        System.out.println("==============channel-active==============");    }    @Override    public void channelInactive(ChannelHandlerContext ctx) throws Exception {        System.out.println("==============channel-inactive==============");    }    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        System.out.println("==============channel-read==============");        System.out.println("the msg type is " + msg.getClass().getName());        Integer integer = (Integer) msg;        System.out.println("服务器端接收到的客户端的数字是" + integer);        System.out.println("服务器向客户端写入整型数字2000");        ctx.writeAndFlush(2000);        ctx.close();    }    @Override    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {        System.out.println("==============channel-read-complete==============");        ctx.flush();    }}

客户端程序

package codec;import codec.decoder.ByteToIntegerDecoder;import codec.encoder.IntegerToByteEncoder;import io.netty.bootstrap.Bootstrap;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.NioSocketChannel;public class HelloClient {    public void connect(String host, int port) throws Exception {        EventLoopGroup workerGroup = new NioEventLoopGroup();        try {            Bootstrap b = new Bootstrap();            b.group(workerGroup);            b.channel(NioSocketChannel.class);            b.option(ChannelOption.AUTO_READ, true);            b.handler(new ChannelInitializer
() {                @Override                public void initChannel(SocketChannel ch) throws Exception {                    ch.pipeline().addLast(                            new IntegerToByteEncoder(),                            new ByteToIntegerDecoder(),                            new HelloClientIntHandler());                }            });            ChannelFuture f = b.connect(host, port).sync();            f.channel().closeFuture().sync();        } finally {            workerGroup.shutdownGracefully();        }    }    public static void main(String[] args) throws Exception {        HelloClient client = new HelloClient();        client.connect("192.168.0.102", 12345);    }}
package codec;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;//InboundHandler类型public class HelloClientIntHandler extends ChannelInboundHandlerAdapter {    @Override    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {        System.out.println("==============channel--register==============");    }    @Override    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {        System.out.println("==============channel--unregistered==============");    }    @Override    public void channelInactive(ChannelHandlerContext ctx) throws Exception {        System.out.println("==============channel--inactive==============");    }    // 连接成功后,向server发送消息    @Override    public void channelActive(ChannelHandlerContext ctx) throws Exception {        System.out.println("==============channel--active==============");        System.out.println("向服务器端写入1991数字");        ctx.write(1991);        ctx.flush();    }    // 接收server端的消息,并打印出来    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        System.out.println("==============channel--read==============");        System.out.println("the msg type is " + msg.getClass().getName());        Integer result = (Integer) msg;        System.out.println("接收到服务器数据整形是" + result);    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {        cause.printStackTrace();        ctx.close();    }}

运行结果:

服务器端

==============handler-sharable==============

==============channel-register==============

==============channel-active==============

==============channel-read==============

the msg type is java.lang.Integer

服务器端接收到的客户端的数字是1991

服务器向客户端写入整型数字2000

ByteToIntegerDecoder decode msg is 1991

IntegerToByteEncoder encode msg is 2000

==============channel-read-complete==============

==============channel-inactive==============

==============channel-unregister==============

客户端

==============channel--register==============

==============channel--active==============

向服务器端写入1991数字

IntegerToByteEncoder encode msg is 1991

ByteToIntegerDecoder decode msg is 2000

==============channel--read==============

the msg type is java.lang.Integer

接收到服务器数据整形是2000

==============channel--inactive==============

==============channel--unregistered==============

Process finished with exit code 0

=======END=======

转载于:https://my.oschina.net/xinxingegeya/blog/282970

你可能感兴趣的文章
IIS7下使用urlrewriter.dll配置
查看>>
并行程序设计学习心得1——并行计算机存储
查看>>
bulk
查看>>
C++ 迭代器运算
查看>>
【支持iOS11】UITableView左滑删除自定义 - 实现多选项并使用自定义图片
查看>>
【算法笔记】多线程斐波那契数列
查看>>
java8函数式编程实例
查看>>
jqgrid滚动条宽度/列显示不全问题
查看>>
在mac OS10.10下安装 cocoapods遇到的一些问题
查看>>
css技巧
查看>>
Tyvj 1728 普通平衡树
查看>>
javascript性能优化
查看>>
多路归并排序之败者树
查看>>
java连接MySql数据库
查看>>
转:Vue keep-alive实践总结
查看>>
深入python的set和dict
查看>>
Android JSON数据解析
查看>>
DEV实现日期时间效果
查看>>
java注解【转】
查看>>
centos 下安装g++
查看>>