Netty学习笔记四:Echo服务和Netty项目的搭建

Netty学习笔记四:Echo服务和Netty项目的搭建

文章目录

      • Netty学习笔记四:Echo服务和Netty项目的搭建
        • 什么是Echo服务
        • Echo服务端程序编写
        • Echo客户端编写
        • Echo服务中的名词解析

什么是Echo服务

  1. Echo服务就是一个应答服务,客户端发送什么数据,服务端就响应对应的数据,是一个非常有的用于调试和检测的服务。

Echo服务端程序编写

  1. EchoServer服务端

一、绑定端口

二、创建主从线程组

三、启动线程组,指定通道 类型,处理传过来的数据内容。

四、监听端口,关闭端口

五、释放线程。

public class EchoServer {
    private int port;
    public EchoServer(int port){
        this.port=port;
    }
    public void run() throws InterruptedException {
        //创建主从线程组。
        EventLoopGroup bossGroup=new NioEventLoopGroup();
        EventLoopGroup workGroup=new NioEventLoopGroup();
        try{
            //配置线程组启动类,Netty框架已经封装好了。创建一个启动对象
            ServerBootstrap serverBootstrap=new ServerBootstrap();
            //将需要启动的线程组包裹进去。//可以通过链式的调用方法,指定Channel类型。
            serverBootstrap.group(bossGroup,workGroup)
                .channel(NioServerSocketChannel.class)//每启动一个线程组就要指定一个通道类型。
                .childHandler(new ChannelInitializer<SocketChannel>() {//当建立通道连接时需要进行处理。
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new EchoServerHandler());
                    }
                });
            System.out.println("Echo 服务器启动ing");
            //绑定端口,需要同步等待。
            ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
            //等待服务端,监听端口关闭
            channelFuture.channel().closeFuture().sync();
        }finally {
            //优雅退出,释放线程池。
            workGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        int port =7070;
        if(args.length>0){
            port=Integer.parseInt(args[0]);
        }
        new EchoServer(port).run();
    }
}
  1. 处理类
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
       //ByteBuf是Netty封装的ByteBuffer。
        ByteBuf data= (ByteBuf)msg;
        System.out.println("服务端收到数据:"+data.toString(CharsetUtil.UTF_8));
        //回写过去,并刷新管道。
        ctx.writeAndFlush(data);
    }
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println("EchoServerHandle channelReadComplete");
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

Echo客户端编写

  1. EchoClient主类
public class EchoClient {
    private int port;
    private String host;
    public EchoClient(String host,int port){
        this.port=port;
        this.host=host;
    }
    public void start() throws InterruptedException {
        EventLoopGroup group=new NioEventLoopGroup();
        try{
            Bootstrap bootstrap =new Bootstrap();
            bootstrap.group(group)
                .channel(NioSocketChannel.class)
                .remoteAddress(new InetSocketAddress(host,port))
                .handler(new ChannelInitializer<SocketChannel>() {
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new EchoClientHandler());
                    }
                });
            //连接到服务器,connect是异步连接,在调用同步等待sync,等待连接成功。
            ChannelFuture channelFulture = bootstrap.connect().sync();
            //阻塞住,直到客户端通道关闭。
            channelFulture.channel().closeFuture().sync();
        }finally {
            //优雅退出释放NIO线程。
            group.shutdownGracefully();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        new EchoClient("127.0.0.1",7070).start();
    }
}
  1. EchoClientHandler处理类

一、与服务端处理类继承的不一样,但是实质是一样的。

二、打印顺序是,先走Active()方法,先激活,表示和服务端建立了通道。

三、读取服务端的数据,

四、读取完成。进入channelReadComplete()方法。

public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
        System.out.println("Client received...."+msg.toString(CharsetUtil.UTF_8));
    }
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("Active");
        //创建一个缓存。使用Unpooled工具类。
        ctx.writeAndFlush(Unpooled.copiedBuffer("世界你好,我是zkf",CharsetUtil.UTF_8));
    }
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println("EchoClient channelReadComplete");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

Echo服务中的名词解析

  1. EventLoop和EventLoopGroup

线程和线程组,前者可以理解为线程,后者可以理解为线程组。

  1. BootStrap

启动引导类,用于配置线程组,启动的时候,同时启动线程组,以及开启通道,初始化通道。和一些处理。

  1. channel

channel是客户端和服务端建立的一个连接,是一个Socket连接,具有生命周期,建立成功,读取数据,读取完成,出现异常等。

  1. channelHandler和channelPipeline

channelhandler是做处理的,对接收的数据进行处理到要直接或间接继承channelHandler。

channelPipeline就好比一个处理工厂,可以添加很多handler处理类,当进入channelHandler后都要经过pipeline添加的handler进行处理。

  1. 个人理解:

就像一个滤水系统,BootStrap是滤水系统的开关,它将滤水系统与水资源连接起来,然后产生一个通道Channel,每个通道里面有一个净水处理系统,即:ChannelHandler,每个净水系统里面有很多处理管道,即:Handler,处理管道是活的,可以添加,卸掉。这些动作都要pipeline这个工具类来实现。

你可能感兴趣的:(Netty架构学习笔记)