8、IO模型部分实现推导

		<dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.49.Final</version>
        </dependency>

测试demo:

import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.buffer.UnpooledByteBufAllocator;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;

public class MyNetty {

    @Test
    public void myBytebuf() {
        // 池化的
//        ByteBuf buf = ByteBufAllocator.DEFAULT.buffer(8, 20);// 初始大小和最大大小

        // 非池化的
        ByteBuf buf = UnpooledByteBufAllocator.DEFAULT.heapBuffer(8, 20);

        print(buf);
        buf.writeBytes(new byte[]{1, 2, 3, 4});
        print(buf);
        buf.writeBytes(new byte[]{1, 2, 3, 4});
        print(buf);
        buf.writeBytes(new byte[]{1, 2, 3, 4});
        print(buf);
        buf.writeBytes(new byte[]{1, 2, 3, 4});
        print(buf);
        buf.writeBytes(new byte[]{1, 2, 3, 4});
        print(buf);

        // 写第6次会超出20上限,所以会报错
        buf.writeBytes(new byte[]{1, 2, 3, 4});
        print(buf);
    }

    public static void print(ByteBuf buf) {
        System.out.println("buf.isReadable():   " + buf.isReadable());  // 是否可读
        System.out.println("buf.readerIndex():   " + buf.readerIndex());  // 从哪读
        System.out.println("buf.readableBytes():   " + buf.readableBytes());  // 读多少
        System.out.println("buf.isWritable():   " + buf.isWritable());  // 是否可写
        System.out.println("buf.writerIndex():   " + buf.writerIndex());  // 写的位置
        System.out.println("buf.writableBytes():   " + buf.writableBytes());  // 写多少
        System.out.println("buf.capacity():   " + buf.capacity());  // 真实分配的上限
        System.out.println("buf.maxCapacity():   " + buf.maxCapacity());  // 期望的上限
        System.out.println("buf.isDirect():   " + buf.isDirect());  // 是否为堆外分配
        System.out.println("==========================================================================");
    }

    @Test
    public void loopExecutor() throws IOException {
        // 线程池,给定1个线程,就只有1个线程执行
        NioEventLoopGroup selector = new NioEventLoopGroup(2);
        selector.execute(() -> {
            try {
                for (; ; ) {
                    System.out.println("hello001");
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        // 因为给了2个线程,所以下面这个线程才会执行
        selector.execute(() -> {
            try {
                for (; ; ) {
                    System.out.println("hello002");
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.in.read();
    }

    /*
    客户端连接别人:
    1, 主动连接
    2, 别人什么时候给我发?
     */
    @Test
    public void clientMode() throws Exception {
        NioEventLoopGroup thread = new NioEventLoopGroup(1);
        // 客户端模式
        NioSocketChannel client = new NioSocketChannel();
        thread.register(client);    // 相当于epoll_ctl

        // 响应式:
        ChannelPipeline pipeline = client.pipeline();
        pipeline.addLast(new MyInHandler());

        // 在服务端开启端口测试是否连接:   nc -l  10.10.10.101 9090
        ChannelFuture connect = client.connect(new InetSocketAddress("10.10.10.101", 9090));
        ChannelFuture sync = connect.sync();
        ByteBuf buf = Unpooled.copiedBuffer("Hello Server".getBytes());
        ChannelFuture send = client.writeAndFlush(buf);
        send.sync();

        sync.channel().closeFuture().sync();
        // 服务端断开连接就打印
        System.out.println("client over......");

    }

    /*
    用户自己实现的
    不应该加@ChannelHandler.Sharable这个给它
     */
    private class MyInHandler extends ChannelInboundHandlerAdapter {

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

        @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.readCharSequence(buf.readableBytes(), StandardCharsets.UTF_8);
            CharSequence str = buf.getCharSequence(0, buf.readableBytes(), StandardCharsets.UTF_8);
            System.out.println(str);
            ctx.writeAndFlush(buf);
        }
    }

    @Test
    public void serverMode() throws InterruptedException {
        NioEventLoopGroup thread = new NioEventLoopGroup(1);
        NioServerSocketChannel serverSocketChannel = new NioServerSocketChannel();
        thread.register(serverSocketChannel);
        // 不知道什么客户端连接,所以用响应式
        ChannelPipeline pipeline = serverSocketChannel.pipeline();
//        pipeline.addLast(new MyAcceptHandler(thread, new MyInHandler()));// accept接收客户端,并注册selector
        pipeline.addLast(new MyAcceptHandler(thread, new ChannelInit()));// accept接收客户端,并注册selector
        ChannelFuture bind = serverSocketChannel.bind(new InetSocketAddress("192.168.243.1", 9090));
        bind.sync().channel().closeFuture().sync();
        System.out.println("server close...");

    }

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

    private 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 registerd......");
        }

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            SocketChannel client = (SocketChannel) msg;
            // 注册
            selector.register(client);
            // 响应式handler
            ChannelPipeline pipeline = client.pipeline();
            pipeline.addLast(handler);
        }
    }

    // 官方写法
    @Test
    public void nettyClient() throws InterruptedException {
        NioEventLoopGroup group = new NioEventLoopGroup(1);
        Bootstrap bootstrap = new Bootstrap();
        ChannelFuture channelFuture = bootstrap.group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ChannelPipeline pipeline = socketChannel.pipeline();
                        pipeline.addLast(new MyInHandler());
                    }
                })
                .connect(new InetSocketAddress("10.10.10.101", 9090));
        Channel channel = channelFuture.sync().channel();

        ByteBuf buf = Unpooled.copiedBuffer("hello server".getBytes());
        ChannelFuture send = channel.writeAndFlush(buf);
        send.sync();
        channel.closeFuture().sync();
    }

    @Test
    public void nettyServer() throws InterruptedException {
        NioEventLoopGroup group = new NioEventLoopGroup(1);
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        ChannelFuture channelFuture = serverBootstrap.group(group, group)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        ChannelPipeline pipeline = nioSocketChannel.pipeline();
                        pipeline.addLast(new MyInHandler());
                    }
                })
                .bind(new InetSocketAddress("192.168.243.1", 9090));
        channelFuture.channel().closeFuture().sync();
    }
}
posted @ 2022-11-25 15:53  aBiu--  阅读(28)  评论(0编辑  收藏  举报