Reactor开发模式
SocketChannel 在client端监听op_connect,op_write,op_read事件,在server只监听op_write,op_read事件,ServerSocketChannel在server端运行,只监听op_accept事件

netty对Reactor模式的实现
首先ServerSocketChannel是能够创立子的socketchannel,创立是由
BootstrapChannelFactory这个工厂类依据传入的class反射来创立,
所以
serverBootstrap.group().channel(xxx.class) .channel这个时候就是由下面的工厂类利用反射动静的创立一个channel,绑定在对应的group上

serverBootstrap.group(bossGroup,workerGroup) .channel传进来的会创立一个channel绑定在bossGroup上,而后传进来的ServerSocketChannel能够创立子socketchannel绑定在wokergroup上

再和下面的reactor开发模式对应,就是serversocketchannel绑定在bossGroup上来负责监听op_accept事件,socketchannel绑定在workergroup上来负责监听其余read write事件

粘包和半包

TCP为什么会呈现粘包和半包(UDP其实没有这个问题):次要是因为TCP是流协定

罕用的解决这种问题的计划:要么短链接,要么长链接中采纳封装成桢framing技术

netty对应用Framing粘包半包的反对:
固定长度的形式:肯定就按固定长度的来传,不够就补空,解码FixedLengthFrameDecoder
宰割符的形式:以指定的宰割符来宰割,但要思考内容中如果有这个宰割符须要本义,解码DelimiterBasedFrameDecoder
固定长度字段存内容的长度信息:要思考预留多少位来存储这个长度,解码器是LengthFieldBasedFramedDecoder,编码器LengthFieldPrepender

下面的编码器都继承了ByteToMessageDecoder这个抽象类

ByteToMessageDecoder 继承 ChannelInboundHandlerAdapter
ChannelInboundHandlerAdapter 中有一个channelRead办法解决数据,ByteToMessageDecoder 中就具体实现了channelRead办法
ByteToMessageDecoder中保护了一个ByteBuf类型的数据积攒器cumulation,如果是第一笔数据间接赋值给cumulation,不是第一笔的就追加在cumulation前面,而后调

  callDecode(ctx, cumulation, out);    //其中callDecode中会调  decodeRemovalReentryProtection(ctx, in, out);  //而后这个又会调decode(ctx, in, out);//这个decode是ByteToMessageDecoder中提供的形象办法,具体由下面的各种Decoder来实现  

以FixedLengthFrameDecoder为例子

public class FixedLengthFrameDecoder extends ByteToMessageDecoder {    private final int frameLength;    public FixedLengthFrameDecoder(int frameLength) {        if(frameLength <= 0) {            throw new IllegalArgumentException("frameLength must be a positive integer: " + frameLength);        } else {            this.frameLength = frameLength;        }    }    protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {        Object decoded = this.decode(ctx, in);        if(decoded != null) {            out.add(decoded);//每一次解进去的数据放在out中        }    }    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {        return in.readableBytes() < this.frameLength?null:in.readSlice(this.frameLength).retain();        //如果以后积攒器就是这里的in中的数据小于定义的长度,不做任何操作,这个时候数据也不够,超过定义的长度,取frameLength长度的数据进去,剩下的就还在积攒器中    }