0
点赞
收藏
分享

微信扫一扫

基础算法(二)#蓝桥杯

在这里插入图片描述

一、客户端代码及关键类说明

/**
 * netty5的客户端
 * @author -zhengzx-
 *
 */
public class ClientSocket {

    public static void main(String[] args) {
        //服务类
        Bootstrap bootstrap = new Bootstrap();
        //worker
        EventLoopGroup worker = new NioEventLoopGroup();
        
        try {
            //设置线程池
            bootstrap.group(worker);
            //设置socket工厂
            bootstrap.channel(NioSocketChannel.class);
            //设置管道
            bootstrap.handler(new ChannelInitializer<Channel>() {

                @Override
                protected void initChannel(Channel ch) throws Exception {
                    ch.pipeline().addLast(new StringDecoder());
                    ch.pipeline().addLast(new StringEncoder());
                    ch.pipeline().addLast(new ClientSocketHandler());
                }
            });
            
            ChannelFuture connect = bootstrap.connect("127.0.0.1", 10101);
            
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            while(true){
                System.out.println("请输入:");
                String msg = bufferedReader.readLine();
                connect.channel().writeAndFlush(msg);
            }
            
        } catch (Exception e) {
             e.printStackTrace();
        } finally{
            worker.shutdownGracefully();
        }
    }
}

【1】EventLoopGroup 客服端需要指定EvnetLoopGroupNetty5中实例为NioEventLoopGroup:表示一个NIOEvnetLoopGroup
【2】ChannelType 指定 Channel 的类型,客户端为NioSocketChannel。在Netty中,Channel是一个Socket的抽象,它为用户提供了关于Socket状态(是否连接还是断开) 以及对Socket的读写等操作。每当 Netty 建立了一个连接后, 都会有一个对应的 Channel实例。
【3】Handler 设置数据的处理类。

public class ClientSocketHandler extends SimpleChannelInboundHandler<String>{

    @Override
    protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
        System.out.println("客户端接受消息:"+msg);
    }
}

【4】ChannelPipeline 在实例化一个Channel时,必然伴随着实例化一个ChannelPipeline

二、服务端代码及说明

【1】EventLoopGroup 不论是服务器端还是客户端,都必须指定EventLoopGroup. 在这个例子中, 指定了NioEventLoopGroup, 表示一个NIOEventLoopGroup, 不过服务器端需要指定两个EventLoopGroup, 一个是bossGroup, 用于处理客户端的连接请求; 另一个是workerGroup, 用于处理与各个客户端连接的IO操作。
【2】ChannelType 指定Channel的类型. 因为是服务器端, 因此使用了NioServerSocketChannel
【3】Handler 设置数据的处理器。

public class ServerSocketHandler extends SimpleChannelInboundHandler<String>{

    @Override
    protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
        System.out.println(msg);
        //返回字符串
        ctx.writeAndFlush("hi");
    }
    
}

三、Netty5 与 Netty4/Netty3的区别

Netty4Netty5的主要区别在于它们的版本更新以及一些新特性的添加。Netty5是对Netty3的后续版本,因此在架构上进行了一些重大调整,增加了许多新的功能和特性,使得其复杂性相较于Netty3有所增加。然而,Netty4Netty5的设计方式相似,因此它们之间的差异并不是特别大。简而言之,Netty5提供了比Netty3更多的高级功能和新特性,而Netty4不再作为单独的版本维护,因为它与Netty5的设计和实现相类似。

netty5的复杂性相对于netty3要多一些。架构基本被重构了。所以这里主要是介绍一些属性和用法。

核心的变化主要有:
【1】支持Android,使得移动设备变的更加强大;
【2】通过Ice Cream Sandwich解决了在ADK中最著名的与NIOSSLEngine相关的问题,且用户显然想要重用他们应用中的的编解码和处理器代码;
【3】我们决定官方支持Android(4.0及以上版本)

简化处理器层次:
【1】ChannelInboundHandlerChannelOutboundHandler整合为ChannelHandlerChannelHandler现在包含输入和输出的处理方法。
【2】ChannelInboundHandlerAdapterChannelOutboundHandlerAdapterChannelDuplexHandlerAdapter已被废弃,由ChannelHandlerAdapter代替。
【3】由于现在无法区分处理器handler)是输入还是输出的处理器,CombinedChannelDuplexHandler现在由ChannelHandlerAppender代替。

Channel.deregister()已被移除。不再生效和被使用。取而代之的,我们将允许Channel被充注册到不同的事件循环。

ChannelHandlerContext.attr(..) == Channel.attr(..)

Channel和ChannelHandlerContext类都实现了AttributeMap接口,使用户可以在其上关联一个或多个属性。有时会让用户感到困惑的是ChannelChannelHandlerContext都有其自己的存储用户定义属性的容器。例如,即使你通过Channel.attr(KEY_X).set(valueX)给属性'KEY_X’赋值,你却无法通过ChannelHandlerContext.attr(KEY_X).get()方法获取到值。反之亦是如此。这种行为不仅仅令人不解而且还浪费内存。

为了解决这个问题,我们决定每个Channel内部仅保留一个mapAttributeMap总是用AttributeKey作为它的keyAttributeKey确保键的唯一性,因此每个Channel中如果存在一个以上的属性容易是多余的。只要用户把他自己的AttributeKey定义成ChannelHandlerprivate static final变量,就不会有出现重复key的风险。

更简单更精确的缓冲区泄漏追踪: 之前,查找缓冲区泄漏是很困难的,并且泄漏的警告信息也不是很有帮助。现在我们有了增强的泄漏报告机制,该机制会在增长超过上限时触发。

PooledByteBufAllocator成为默认的allocator4.x版本中UnpooledByteBufAllocator是默认的allocator,尽管其存在某些限制。现在PooledByteBufAllocator已经广泛使用一段时间,并且我们有了增强的缓冲区泄漏追踪机制,所以是时候让PooledByteBufAllocator成为默认了。
全局唯一的Channel ID 每个Channel现在有了全局唯一的ID,其生成的依据是:

  • MAC地址(EUI-48或是EUI-64),最好是全局唯一的进程ID
  • System#currentTimeMillis()
  • System#nanoTime()
  • 随机的32位整数,以及系列递增的32位整数;

可通过Channel.id()方法获取ChannelID

更灵活的线程模型: 增加了新的ChannelHandlerInvoker接口,用于使用户可以选择使用哪个线程调用事件处理方法。替代之前的在向ChannelPipeline添加ChannelHandler时指定一个EventExecutor的方式,使用该特性需要指定一个用户自定义的ChannelHandlerInvoker实现。

EmbeddedChannel的易用性: EmbeddedChannel中的readInbound()readOutbound()方法返回专门类型的参数,因此你不必在转换他们的返回值。这可以简化你的测试用例代码。

EmbeddedChannel ch = ...;
 
// BEFORE:
FullHttpRequest req = (FullHttpRequest) ch.readInbound();
 
// AFTER:
FullHttpRequest req = ch.readInbound();

使用Executor代替ThreadFactory: 有些应用要求用户使用Executor运行他们的任务。4.x版本要求用户在创建事件循环event loop时指定ThreadFacotry,现在不再是这样了。

Class loader友好化: 一些类型,如AttributeKey对于在容器环境下运行的应用是不友好的,现在不是了。

编解码和处理器handlers

  • XmlFrameDecoder支持流式的XML文档;
  • 二进制的memcache协议编解码;
  • 支持SPDY/3.1 (也移植到了4.x版本);
  • 重构了HTTP多部分的编解码;
举报

相关推荐

0 条评论