美文网首页
I/O-手写版与官方版netty

I/O-手写版与官方版netty

作者: 麦大大吃不胖 | 来源:发表于2020-12-01 10:17 被阅读0次

by shihang.mai

1. ByteBuf

ByteBuf buf = ByteBufAllocator.DEFAULT.buffer(8, 20);

ByteBuf buf = UnpooledByteBufAllocator.DEFAULT.heapBuffer(8, 20);

ByteBuf buf = PooledByteBufAllocator.DEFAULT.heapBuffer(8, 20);

2. 自行实现client和server

client

public void clientMode() throws Exception{
            //NioEventLoopGroup里面含selector
        NioEventLoopGroup thread = new NioEventLoopGroup(1);

        NioSocketChannel client = new NioSocketChannel();
            //利用ChannelPipeline预埋事件
        ChannelPipeline p = client.pipeline();
        p.addLast(new MyInHandler());
        thread.register(client);

        ChannelFuture connect = client.connect(new InetSocketAddress(9090));
            //连接是异步的
        ChannelFuture sync = connect.sync();
                
        ByteBuf byteBuf = Unpooled.copiedBuffer("hello server".getBytes());
            //发送是异步的
        ChannelFuture send = client.writeAndFlush(byteBuf);
        send.sync();
                //维持当前线程存活,直到连接关闭
        sync.channel().closeFuture().sync();



        System.out.println("client over");

    }
class MyInHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        System.out.println("client registered...");
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("client active...");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf = (ByteBuf)msg;
        CharSequence str = buf.getCharSequence(0,buf.readableBytes(), CharsetUtil.UTF_8);
        System.out.println(str);

        ctx.writeAndFlush(buf);
    }
}

server

public void serverMode() throws Exception{
            //NioEventLoopGroup里面含selector
        NioEventLoopGroup thread = new NioEventLoopGroup(1);

        NioServerSocketChannel server = new NioServerSocketChannel();
        thread.register(server);
        ChannelPipeline p = server.pipeline();
            /*
            * 1.这个ChannelInit类,目的是为了做一个过桥。
        *   2.如果不用这个,直接传入MyInHandler,那么这个MyInHandler必须要用@ChannelHandler.Sharable修饰,并且不能声明全局变量,因为如果这里做传入,那么只有一个这样的类,多个线程会导致全局变量值会超出预期。不应该限制coder不用全局变量,也不应该强加@ChannelHandler.Sharable
        *   3.用ChannelInit类后,那么@ChannelHandler.Sharable修饰的是ChannelInit,并且在ChannelInit类中,每次来一个请求,都new MyInHandler(),并把这个桥remove掉,因为留着也没用,只关注业务handler即可。
            */
        p.addLast(new MyAcceptHandler(thread,new ChannelInit()));
        ChannelFuture bind = server.bind(new InetSocketAddress(9090));
        bind.sync().channel().closeFuture().sync();

        System.out.println("server close....");
    }
class MyAcceptHandler extends ChannelInboundHandlerAdapter{
    private final EventLoopGroup selector;
    private final ChannelHandler handler;

    public MyAcceptHandler(EventLoopGroup thread, ChannelHandler myInHandler) {
        this.selector = thread;
        this.handler = myInHandler;
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        System.out.println("server registered");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        SocketChannel client = (SocketChannel) msg;
        ChannelPipeline p = client.pipeline();
        p.addLast(handler);
        selector.register(client);


    }
}
@ChannelHandler.Sharable
class ChannelInit extends ChannelInboundHandlerAdapter{
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        Channel client = ctx.channel();
        ChannelPipeline p = client.pipeline();
        p.addLast(new MyInHandler());
        ctx.pipeline().remove(this);
    }
}

3. 官方版client和server

client

public void nettyClient() throws Exception{
        NioEventLoopGroup group = new NioEventLoopGroup(1);
        Bootstrap bs = new Bootstrap();
        ChannelFuture connect = bs.group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline p = ch.pipeline();
                        p.addLast(new MyInHandler());
                    }
                })
                .connect(new InetSocketAddress(9090));
        Channel client = connect.sync().channel();
        ByteBuf byteBuf = Unpooled.copiedBuffer("hello server".getBytes());
        ChannelFuture send = client.writeAndFlush(byteBuf);
        send.sync();
        client.closeFuture().sync();
    }

server

public void nettyServer() throws Exception{
        NioEventLoopGroup group = new NioEventLoopGroup(1);
        ServerBootstrap bs = new ServerBootstrap();
        ChannelFuture bind = bs.group(group, group)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ChannelPipeline p = ch.pipeline();
                        p.addLast(new MyInHandler());
                    }
                })
                .bind(new InetSocketAddress(9090));
        bind.sync().channel().closeFuture().sync();
    }

相关文章

网友评论

      本文标题:I/O-手写版与官方版netty

      本文链接:https://www.haomeiwen.com/subject/jploiktx.html