《Netty实战》第一部分

本文介绍了Netty实战中关于Channel的概念,强调了Channel的线程安全性和与EventLoop的绑定。讲解了ByteBuf的特性,如堆缓冲区、直接缓冲区和复合缓冲区,以及ByteBuf的操作方法。同时,提到了ChannelHandler及其相关接口,如ChannelInboundHandler和ChannelOutboundHandler,用于处理入站和出站事件,并介绍了ChannelPipeline和ChannelHandlerContext在数据传输中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

从开始打算学Netty,然后很自然的找到了《Netty实战》这本书,但是,对一个从来没写过的Netty程序的人而言,理解书中的概念确实很难呀。更何况,还几乎没有Nio网络编程的基础,所以一度书看不下去,但觉得写Netty程序不算什么很难的事情。
后来,由于一些需要,自己开始写Netty服务端和客户端,时常出现服务端发不出去消息,或者客户端收不到消息。并且用的Kotlin,异常都没有受检,就更加找不到错误了。这时回过头来看看《Netty实战》才感觉收获很多。

Channel

代表一个通道,连接客户端和服务端两头,两头都可以往Channel里面写/读东西。且Channel的读写是线程安全的。
一个Channel与一个EventLoop绑定,而一个EventLoop可以视为一个线程,用于处理Channel的回调事件。
ChannelRegistered   ->   ChannelActive
                              |
                              \/
ChannelUnregistered <-  ChannelInactive

这里写图片描述

这里写图片描述

由类图可以得到一些信息:Comparable接口保证Channel是独一无二的,AttributeMap有attr(AttrubuteKey< T >)和hasAttr(AttrubuteKey< T >)
通过localAddress()和remoteAddress()可以获取连接的信息,此外isXXX()很好理解,write(),read(),flush()也很常见。
此外很重要的是pipeline()和config()这两个方法, ChannelPipeline持有所有入站和出站的ChannelHandler. 而ChannelConfig,看下图吧

这里写图片描述

unsafe()返回一个Unsafe对象,可以更改Channel的基本信息,如bind一个新的端口,connect一个新的远程地址…

这里写图片描述

还有Channel的父接口ChannelOutboundInvoker, 根据文档,说明write()方法是通过代理ChannelHandlerContext对象来实现的

这里写图片描述

常用的Channel

名称 包名 描述
NIO io.netty.channel.socket.nio 基于java.nio.channels的Selector
Epoll io.netty.channel.epoll 使用jni的eqoll()和非堵塞io,只在Linux可用的特性,速度更快
OIO io.netty.channel.socket.oio 基于java.net的堵塞Stream实现
Local io.netty.channel.local 在VM内部的管道传输
Embedded io.netty.channel.embedded 多用于测试ChannelHandler

ByteBuf

Netty的数据传输通过ByteBuf(抽象类)和ByteBufHolder(接口)来暴露。
相比于ByteBuffer而言,ByteBuf有以下优点:可自行扩展,复合缓冲器类型零拷贝,容量自动增长,读写切换不需要flip,读写使用不同的索引,支持链式调用,支持引用计数,支持池化。

这里写图片描述
这里写图片描述

Bytebuf有readerIndex和writerIndex, readerIndex不能超过可读的索引,否则会抛出异常。

缓冲区类型

堆缓冲区:分配释放很快,读写较慢
ByteBuf heapBuf = ...
if(heapBuf.hasArray()){               //只有堆缓存有支撑数组,判断是不是堆缓存
    byte[] array = heapBuf.array();   //如果有,获取数组的引用
    int offset = heapBuf.arrayOffset() + heapBuf.readerIndex();//计算第一个字节的偏移量
    int length = heapBuf.readableBytes();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值