作者:瑞奇杨

资料来源:www.cnblogs.com/rickiyang

在本节中,我们将讨论Netty。在使用Netty之前,我们先看看Netty能做什么,什么都不做就能学会。不是徒劳的!

1.Netty可以做什么?

异步无阻塞TCP网络应用程序开发异步无阻塞UDP网络应用程序开发异步文件传输应用程序开发异步HTTP服务器和客户端应用程序开发提供了多种编解码器框架的集成,包括Google的Protobuf、Jboss marshalling、Java序列化、压缩编解码器、XML解码、字符串编解码器等。这些编解码器框架可供用户直接使用。提供多种格式的编解码器基类库,使专用堆栈编解码器框架的二次自定义和开发变得更加容易。基于角色链模式的Pipeline-Handler机制使用户能够轻松拦截和自定义网络事件。所有IO操作都是异步的,用户可以通过故障侦听器机制主动获得Get结果,也可以在IO线程操作完成后获得主动Notify结果,用户的业务线程不需要同时等待。IP黑白列表控制;基于消息码流打印流控制和成型性能统计链路空闲事件检测的心跳检测2。Netty通用类说明

在这里,我们大致说明了我们常用的几个类,然后在写入门程序的时候,大致知道每行说了什么。(约翰f肯尼迪)。

EventLoop,EventLoopGroup

EventLoop目的是为Channel处理IO操作,一个EventLoop可以为多个Channel服务,EventLoopGroup会包含多个EventLoop。

BootStrap,ServerBootstrap

一个Netty应用通常由一个Bootstrap开始,它主要作用是配置整个Netty程序,串联起各个组件。分享:Spring Boot 学习笔记。

ChannelInitializer

当一个链接建立时,我们需要知道怎么来接收或者发送数据,当然,我们有各种各样的Handler实现来处理它,那么ChannelInitializer便是用来配置这些Handler,它会提供一个ChannelPipeline,并把Handler加入到ChannelPipeline。

Handler

为了支持各种协议和处理数据的方式,便诞生了Handler组件。Handler主要用来处理各种事件,这里的事件很广泛,比如可以是连接、数据接收、异常、数据转换等。

ChannelInboundHandler

一个最常用的Handler。这个Handler的作用就是处理接收到数据时的事件,也就是说,我们的业务逻辑一般就是写在这个Handler里面的,ChannelInboundHandler就是用来处理我们的核心业务逻辑。

Future

在Netty中所有的IO操作都是异步的,因此,你不能立刻得知消息是否被正确处理,但是我们可以过一会等它执行完成或者直接注册一个监听,具体的实现就是通过Future和ChannelFutures,他们可以注册一个监听,当操作执行成功或失败时监听会自动触发。总之,所有的操作都会返回一个ChannelFuture。

3. 第一个Helloworld

上面我们已经对常用类进行说明,下面我们就使用这些类来构建我们的第一个入门程序,本示例我使用的是maven来构建工程,如果你使用的是普通的项目则跳过第一步。另外,微信搜索Java技术栈,在后台回复:Maven,获取系列 Maven 教程。

首先引入maven jar包:

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

下面我们来写客户端:

public class HelloWorldClient {
    private  int port;
    private  String address;

    public HelloWorldClient(int port,String address) {
         = port;
         = address;
    }

    public void start(){
        EventLoopGroup group = new NioEventLoopGroup();

        Bootstrap bootstrap = new Bootstrap();
        boo(group)
                .channel)
                .handler(new ClientChannelInitializer());

        try {
            Channel channel = boo(address,port).sync().channel();
            BufferedReader reader = new BufferedReader(new InputStreamReader));
            for(;;){
                String msg = reader.readLine();
                if(msg == null){
                    continue;
                }             
                c(msg + "rn");
            }         
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            group.shutdownGracefully();
        }

    }

    public static void main(String[] args) {
        HelloWorldClient client = new HelloWorldClient(7788,"127.0.0.1");
        client.start();
    }
}

ChannelInitializer用来配置处理数据的handler:

public class ClientChannelInitializer extends  ChannelInitializer<SocketChannel> {

    protected void initChannel(SocketChannel socketChannel) throws Exception {
        ChannelPipeline pipeline = ();

        /*
         * 这个地方的 必须和服务端对应上。否则无法正常解码和编码
         *
         * 解码和编码 我将会在下一节为大家详细的讲解。暂时不做详细的描述
         *
         * /        
        ("decoder", new StringDecoder());
        ("encoder", new StringEncoder());

        // 我们自己的handler
        ("handler", new HelloWorldClientHandler());
    }
}

写一个我们自己的handler,用自己的方式来处理数据:

public class HelloWorldClientHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Sy("server say : "+m());
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Sy("Client is active");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Sy("Client is close");
    }
}

客户端我们写完了,下面开始写服务器端:

public class HelloWordServer {
    private int port;

    public HelloWordServer(int port) {
         = port;
    }

    public void start(){
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workGroup = new NioEventLoopGroup();

        ServerBootstrap server = new ServerBootstrap().group(bossGroup,workGroup)
                                    .channel)
                                    .childHandler(new ServerChannelInitializer());

        try {
            ChannelFuture future = (port).sync();
            ().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            bo();
            workGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        HelloWordServer server = new HelloWordServer(7788);
        ();
    }
}

服务端的ChannelInitializer:

public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        ChannelPipeline pipeline = ();      

        // 字符串解码 和 编码
        ("decoder", new StringDecoder());
        ("encoder", new StringEncoder());

        // 自己的逻辑Handler
        ("handler", new HelloWordServerHandler());
    }
}

服务器端的handler:

public class HelloWordServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Sy().remoteAddress()+"===>server: "+m());
        c("received your msg");
        c();
    }

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

上面服务器端和客户端的代码都已经写完,下面我们先启动服务端,然后启动客户端,程序中我是在客户端让手动输入,输入结束之后回车,服务器端即可接受数据。

客户端:

服务端:

1.《【unhandled exception caught】Netty 简易实战,傻瓜都能看懂》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

2.《【unhandled exception caught】Netty 简易实战,傻瓜都能看懂》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

3.文章转载时请保留本站内容来源地址,https://www.cxvn.com/gl/djyxgl/229856.html