Netty入门教程

Netty 介绍

随着Java NIO的普及,越来越多基于nio的框架应运而生,netty便是其中之一,netty提供更快更容易的方式去操作实现各个通信协议,包括http tcp udpftp,smtp等等。

Netty 是一个高效的提供异步事件驱动的网络通信框架,换而言之,netty是一个nio实现框架并且能简化传统的tcp udp socket 编程。

Netty 编程

1.处理类

Client处理类

继承SimpleChannelInboundHandler类并重写相应方法如channelActive,channelRead和exceptionCaught

 
 
 
 
 
public class DiscardClientHandler extends SimpleChannelInboundHandler<Object> {
    private ByteBuf content;
    private ChannelHandlerContext ctx;
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        this.ctx = ctx;
        // Initialize the message.
        content = ctx.alloc().directBuffer(DiscardClient.SIZE).writeZero(DiscardClient.SIZE);
        // Send the initial messages.
        generateTraffic();
    }
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        content.release();
    }
    @Override
    public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        // Server is supposed to send nothing, but if it sends something, discard it.
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // Close the connection when an exception is raised.
        cause.printStackTrace();
        ctx.close();
    }
    long counter;
    private void generateTraffic() {
        // Flush the outbound buffer to the socket.
        // Once flushed, generate the same amount of traffic again.
        ctx.writeAndFlush(content.retainedDuplicate()).addListener(trafficGenerator);
    } c
    private final ChannelFutureListener trafficGenerator = new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) {
            if (future.isSuccess()) {
                generateTraffic();
            } else {
                future.cause().printStackTrace();
                future.channel().close();
            }
        }
    };
}
 
Server处理类

同样继承SimpleChannelInboundHandler 并重写channelRead0和exceptionCaught方法

 
 
 
 
 
public class DiscardServerHandler extends SimpleChannelInboundHandler<Object> {
    @Override
    public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        // discard
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // Close the connection when an exception is raised.
        cause.printStackTrace();
        ctx.close();
    }
}
 

2.连接类

Client连接

客户端连接需要用到Bootstrap和EventLoopGroup类,并借助ChannelInitializer将对应的处理器绑定

 
 
 
 
 
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
             .channel(NioSocketChannel.class)
             .handler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 protected void initChannel(SocketChannel ch) throws Exception {
                     ChannelPipeline p = ch.pipeline();
                     if (sslCtx != null) {
                         p.addLast(sslCtx.newHandler(ch.alloc(), HOST, PORT));
                     }
                     p.addLast(new DiscardClientHandler());
                 }
             });
            // Make the connection attempt.
            ChannelFuture f = b.connect(HOST, PORT).sync();
            // Wait until the connection is closed.
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
 
Server连接

server连接需要两个EventLoopGroupon进行,boss负责接收请求,worker进行相应处理 ,并且使用ServerBootstrap进行连接。

 
 
 
 
 
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .handler(new LoggingHandler(LogLevel.INFO))
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) {
                     ChannelPipeline p = ch.pipeline();
                     if (sslCtx != null) {
                         p.addLast(sslCtx.newHandler(ch.alloc()));
                     }
                     p.addLast(new DiscardServerHandler());
                 }
             });
            // Bind and start to accept incoming connections.
            ChannelFuture f = b.bind(PORT).sync();
            // Wait until the server socket is closed.
            // In this example, this does not happen, but you can do that to gracefully
            // shut down your server.
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
 

以上就是一个简单的netty实例:

3.重要类分析:

io.netty.buffer. ByteBuf
 
 
 
 
 
public abstract class ByteBuf extends Object implements ReferenceCounted, Comparable<ByteBuf>
 

ByteBuf 提供了两个指针来进行顺序的读和写。- readerIndex 读操作 and writerIndex 写操作.

​ +-----------------------------------+--------------------------------------+------------------------------------------------+​ | discardable bytes | readable bytes | writable bytes |​ | | (CONTENT) | |​ +-----------------------------------+---------------------------------------+-----------------------------------------------+​ | | | |​ 0 <= readerIndex <= writerIndex <= capacity

 

 

posted @ 2017-04-13 15:27  xwine  阅读(887)  评论(0)    收藏  举报