Netty学习(一)—基本使用

来源:互联网 发布:免费扫描软件 编辑:程序博客网 时间:2024/05/14 06:31

Netty学习(一)—基本使用

Netty是基于Java NIO实现的Socket通信框架,相比于Java NIO操作更加简便同时一些改进也使其性能相对更好;

个人主页:tuzhenyu’s page
原文地址:Netty学习(一)—基本使用

(0) 基于Netty服务端的创建

  • 服务端启动

    • 创建NioEventLoopGroup线程池实例来处理事件,如接受连接,读写数据等;

    • 创建ServerBootstrap启动辅助类,相当于一个参数集合,接受服务端各个参数配置;

    • 配置绑定EventLoopGroup线程池,绑定两个线程池一个用来处理连接一个用来处理读写数据;

    • 配置服务端通道类型,包括NioServerSocketChannel,OioServerSocketChannel等;

    • 配置服务端处理器Handler,负责服务端处理逻辑;

public class NettyServer {    private void bind(int port){        EventLoopGroup bossGroup = new NioEventLoopGroup();        EventLoopGroup workerGroup = new NioEventLoopGroup();        try{            ServerBootstrap b= new ServerBootstrap();            b.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class)                    .option(ChannelOption.SO_BACKLOG,1024)                    .childHandler(new ChannelInitializer<SocketChannel>() {                        @Override                        protected void initChannel(SocketChannel socketChannel) throws Exception {                            socketChannel.pipeline().addLast(new ServerHandler2());                        }                    });            ChannelFuture f = b.bind(port).sync();            f.channel().closeFuture().sync();        } catch (Exception e){            e.printStackTrace();        }finally {            bossGroup.shutdownGracefully();            workerGroup.shutdownGracefully();        }    }    public static void main(String[] args) {        NettyServer server = new NettyServer();        server.bind(8008);    }}
  • 服务端逻辑

    • 创建服务端数据处理器Handler,继承ChannelInboundHandlerAdapter,ChannelOutboundHandelrAdapter和SimpleChannelInboundHandler等用来对输入流或者输出流进行处理;

    • 实现channelActive(),channelRead(),channelInActive(),channelReadComplete(),exceptionCought()方法等对输入流进行处理;

    • 实现write(),close()等方法对输出流进行处理

class ServerHandler extends ChannelInboundHandlerAdapter{    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        ByteBuf buf = (ByteBuf)msg;        byte[] bytes = new byte[buf.readableBytes()];        buf.readBytes(bytes);        System.out.println(new String(bytes,"UTF-8"));    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {        ctx.close();    }}

(1) 基于Netty客户端的创建

  • 客户端的启动
public class NettyClient {    private void connect(String host,int port){        EventLoopGroup group = new NioEventLoopGroup();        try {            Bootstrap b = new Bootstrap();            b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY,true)                    .handler(new ChannelInitializer<SocketChannel>() {                        @Override                        protected void initChannel(SocketChannel socketChannel) throws Exception {                            socketChannel.pipeline().addLast(new ClientHandler());                        }                    });            ChannelFuture f = b.connect(host,port).sync();            f.channel().closeFuture().sync();        }catch (Exception e){            e.printStackTrace();        }finally {            group.shutdownGracefully();        }    }    public static void main(String[] args) {        NettyClient client = new NettyClient();        client.connect("127.0.0.1",8008);    }}
  • 客户端逻辑实现
class ClientHandler extends ChannelInboundHandlerAdapter{    @Override    public void channelActive(ChannelHandlerContext ctx) throws Exception {        byte[] bytes = "hello,world".getBytes();        ByteBuf buf = Unpooled.buffer(bytes.length);        buf.writeBytes(bytes);        ctx.writeAndFlush(buf);    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {        ctx.close();    }}

(2) 输入流处理器ChannelInboundHandlerAdapter和SimpleChannelInboundHandler

  • ChannelInboundHandlerAdapter和SimpleChannelInboundHandler都是用来处理输入流的,SimpleChannelInboundHandler继承自ChannelInboundHandlerAdapter,只是对传入的数据已经进行了强制类型转换,在输入流处理上两者都能实现;

  • 继承ChannelInboundHandlerAdapter实现自定义输入流处理

class ServerHandler extends ChannelInboundHandlerAdapter{    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        ByteBuf buf = (ByteBuf)msg;        byte[] bytes = new byte[buf.readableBytes()];        buf.readBytes(bytes);        System.out.println(new String(bytes,"UTF-8"));    }}
  • 继承SimpleChannelInboundHandler实现自定义输入流处理
class ServerHandler2 extends SimpleChannelInboundHandler<ByteBuf>{    @Override    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {        byte[] bytes = new byte[msg.readableBytes()];        msg.readBytes(bytes);        System.out.println(new String(bytes,"UTF-8"));    }}

总结

  • 本文以Netty创建客户端和服务端实例总结了客户端服务端创建的整体流程,同时也比较了ChannelInboundHandlerAdapter和SimpleChannelInboundHandler两种 输入流处理器;
原创粉丝点击