Netty学习一:入门案例

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:学习之前,最好能够去官网看看,去github看看使用案例:

Netty例子:https://github.com/netty/netty/tree/4.1/example/src/main/java/io/netty/example


提示:开始第一次学习

一、Netty是什么?

官方定义:Netty 是一个 NIO 客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序;
个人理解:Netty是一个编写服务器的框架,主要作用是定义协议,通俗理解就是定义一个网络中的实体;

二、使用步骤

1.引入库

maven中引入依赖(示例):

        <!--netty依赖-->
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.39.Final</version>
        </dependency>

2.使用案例

服务器端代码如下(示例):

public class Server {
    private static final Logger log = LoggerFactory.getLogger(Server.class);

    private int port;

    public Server(int port) {
        this.port = port;
    }

    public void run() throws Exception {

        NioEventLoopGroup boosGroup = new NioEventLoopGroup();// 1.NioEventLoopGroup是一个处理 I/O 操作的多线程事件循环。NettyEventLoopGroup为不同类型的传输提供了不同的实现
        NioEventLoopGroup workerGroup = new NioEventLoopGroup(2);

        try {
            ServerBootstrap sb = new ServerBootstrap();// 2.ServerBootstrap是一个设置服务器的辅助类。使用来设置服务器Channel
            sb.group(boosGroup,workerGroup)
                    .channel(NioServerSocketChannel.class) //3.在这里,我们指定使用NioServerSocketChannel用于实例化新Channel接受传入连接的类。
                    .childHandler(new ChannelInitializer<SocketChannel>() {// 4、此处指定的处理程序将始终由新接受的Channel. 是一个特殊的ChannelInitializer处理程序,旨在帮助用户配置一个新的Channel.
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new TimeServerHandler());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG,128) // 5、您还可以设置特定于Channel实现的参数。我们正在编写一个 TCP/IP 服务器,因此我们可以设置套接字选项,例如tcpNoDelay和keepAlive。
                    .childOption(ChannelOption.SO_KEEPALIVE,true); // 6、你注意到了option()吗childOption()?option()适用于NioServerSocketChannel接受传入连接的。childOption()是为Channelparent 接受的 s ServerChannel,NioSocketChannel在这种情况下。
            ChannelFuture future = sb.bind(port).sync();

            //等待服务器套接字关闭。
            //关闭您的服务器
            future.channel().closeFuture().sync();
        }finally {
            workerGroup.shutdownGracefully();
            boosGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        int port = 8999;// 端口号

        new Server(port).run(); // 实例化启动
    }
}

客户端代码如下(示例):

public class Client {

    public static void main(String[] args) throws InterruptedException {
//        String host = args[0];
//        int port = Integer.parseInt(args[1]);
        String host = "127.0.0.1";
        int port = 8999;

        NioEventLoopGroup workersGroup = new NioEventLoopGroup();

        try {
            Bootstrap bs = new Bootstrap();// 1.BootstrapServerBootstrap除了它用于非服务器通道(例如客户端或无连接通道)之外,它类似于。
            bs.group(workersGroup);//2.如果您只指定一个EventLoopGroup,它将同时用作老板组和工人组。但是 boss worker 不用于客户端。
            bs.channel(NioSocketChannel.class);// 3.不是NioServerSocketChannel,NioSocketChannel被用来创建客户端Channel.
            bs.option(ChannelOption.SO_KEEPALIVE,true);
            bs.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(new TimeDecoder(),new TimeClientHandler());// 添加通道中的处理器,主要业务写在里面
                }
            });
            // 开启客户端
            ChannelFuture future = bs.connect(host, port).sync();
            // 等待连接关闭
            future.channel().closeFuture().sync();

        }finally {
            workersGroup.shutdownGracefully();
        }
    }
}

将字节转化成实体
代码:实体

public class UnixTime {

    private final long value;

    public UnixTime() {
        this(System.currentTimeMillis() / 1000L + 2208988800L);
    }

    public UnixTime(long value) {
        this.value = value;
    }
    public long value(){
        return value;
    }

    @Override
    public String toString() {
        return new Date((value() - 2208988800L) * 1000L).toString();
    }
}

代码:编码器(编码解析数据时使用)

public class TimeEncoder extends ChannelOutboundHandlerAdapter {

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        UnixTime m = (UnixTime) msg;
        ByteBuf encoded = ctx.alloc().buffer(4);
        encoded.writeInt((int) m.value());
        ctx.write(encoded,promise);
    }
}

代码3:解码器(解码数据时使用)

public class TimeDecoder extends ByteToMessageDecoder {

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        if (byteBuf.readableBytes()<4){
            return;
        }
        list.add(new UnixTime(byteBuf.readUnsignedInt()));
    }
}

总结

  • NioEventLoopGroup():1.NioEventLoopGroup是一个处理 I/O 操作的多线程事件循环。
  • new ServerBootstrap():2.ServerBootstrap是一个设置服务器的辅助类。使用来设置服务器Channel。
  • serverBootstrap.channel(NioServerSocketChannel.class):3.在这里,我们指定使用NioServerSocketChannel用于实例化新Channel接受传入连接的类。指定使用扫描类型的channel。
  • serverBootstrap.childHandler():是一个特殊的ChannelInitializer处理程序,帮助用户配置一个新的Channel。
  • ch.pipeline().addLast():添加通道中的处理器,主要业务写在里面
  • serverBootstrap.option():设置特定于Channel实现的参数,如设置套接字选项。
  • .bind(port).sync();// 绑定端口异步启动
  • future.channel().closeFuture().sync():关闭服务器
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值