netty学习(一)-- 基础理论学习

netty的基础学习

1.是什么?

Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架。Netty 是一个广泛使用的 Java 网络编程框架。是一个用以快速开发高性能、高可靠性协议的服务器和客户端。换句话说,Netty 是一个 NIO 客户端服务器框架,使用它可以快速简单地开发网络应用程序,比如服务器和客户端的协议。Netty 大大简化了网络程序的开发过程比如 TCP 和 UDP 的 socket 服务的开发。

2.有什么特点?

  • 并发高
    Netty是一款基于NIO(Nonblocking I/O,非阻塞IO)开发的网络通信框架,对比于BIO(Blocking I/O,阻塞IO),他的并发性能得到了很大提高。NIO中,当一个Socket建立好之后,Thread并不会阻塞去接受这个Socket,而是将这个请求交给Selector,Selector会不断的去遍历所有的Socket,一旦有一个Socket建立完成,他会通知Thread,然后Thread处理完数据再返回给客户端——这个过程是不阻塞的,这样就能让一个Thread处理更多的请求了。

  • 传输快
    Netty的传输快其实也是依赖了NIO的一个特性—零拷贝。
    Java的内存有堆内存、栈内存和字符串常量池等等,其中堆内存是占用内存空间最大的一块,也是Java对象存放的地方,一般我们的数据如果需要从IO读取到堆内存,中间需要经过Socket缓冲区,也就是说一个数据会被拷贝两次才能到达他的的终点,如果数据量大,就会造成不必要的资源浪费。
    Netty中,需要接收数据的时候,他会在堆内存之外开辟一块内存,数据就直接从IO读到了那块内存中去,在netty里面通过ByteBuf可以直接对这些数据进行直接操作,从而加快了传输速度。

  • 封装好
    netty能通过编程自定义各种协议,因为netty能够通过codec自己来编码/解码字节流,完成类似redis访问的功能。
    netty在应用时,不需要考虑太多问题。比如socket连接的维护、内容传输等。

  • netty的实例
    socket连接的维护和内容传输的字节维护

 @Override
	    public void run() {
	        EventLoopGroup boss = new NioEventLoopGroup();
	        EventLoopGroup worker = new NioEventLoopGroup();
	        try {
	            ServerBootstrap bootstrap = new ServerBootstrap();
	            bootstrap.group(boss, worker);										// 绑定线程池
	            bootstrap.channel(NioServerSocketChannel.class);		// 指定使用的channel
	            bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {// 绑定客户端连接时候触发操作
	                @Override
	                public void initChannel(SocketChannel ch) throws Exception {
	                    String logStr = DateUtil.getDateTime() + " 客户端 " + ch.remoteAddress()+" 准备连接server";
	                    System.out.println(logStr);
	                    //设置接收到数据的长度
	                    //ch.pipeline().addLast(new FixedLengthFrameDecoder(1500));
	                    //读写空闲。第一个参数表示读操作空闲时间;第二个参数表示写操作空闲时间;第三个参数表示读写操作空闲时间; 第四个参数 单位/秒
	                    //ch.pipeline().addLast("ping", new IdleStateHandler(120, 120, 120, TimeUnit.SECONDS));
	                    //长时间不发消息自行断开
	                    ch.pipeline().addLast(new ReadTimeoutHandler(300));

	                    ch.pipeline().addLast(new ByteToMessageDecoder() {			//读取数据的编码设置
							@Override
							protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
								byte[] bytes = new byte[in.readableBytes()];
								in.readBytes(bytes);
								out.add(ConversionUtils.bytes_String16(bytes));
							}
						});
	                    ch.pipeline().addLast(new MessageToByteEncoder<String>(){	//发送数据的编码设置
							@Override
							protected void encode(ChannelHandlerContext ctx, String msg, ByteBuf out) throws Exception {
								byte[] respone = ConversionUtils.hexStrToByteArray(msg);
								out.writeBytes(respone);
							}
	                    });
	                    ch.pipeline().addLast(new TcpEquHandler());	//客户端实例连接的操作类
	                }
	            });
	            ChannelFuture f = bootstrap.bind(port).sync();		// 服务器异步创建绑定
	            f.channel().closeFuture().sync();					// 关闭服务器通道
	        } catch (InterruptedException e) {
	            e.printStackTrace();
	        } finally {
	            boss.shutdownGracefully();			// 释放线程池资源
	            worker.shutdownGracefully();
	        }
	    }
public class TcpEquHandler extends ChannelInboundHandlerAdapter {
	/**
	 * 通道建立事件
	 */
	@Override
	public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
	}

	/**
     * channel 通道 action 活跃的
     * 当客户端主动链接服务端的链接后,这个通道就是活跃的了。也就是客户端与服务端建立了通信通道并且可以传输数据
     */
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    }

    /**
     * channel 通道 Inactive 不活跃的
     * 当客户端主动断开服务端的链接后,这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据
     */
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    }

    /**
     * 接收数据
     * @param ctx 连接对象
     * @param msg 接收到的消息
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg){
    }

    /**
     * 功能:读取完毕客户端发送过来的数据之后的操作
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    /**
     * 读写空闲触发的事件
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值