参考文献:极客时间傅健老师的《Netty源码剖析与实战》Talk is cheap.show me the code!
----主线:
----源码:
在NioEventLoop的unsafe.read()打断点
在客户端关闭的地方也加个断点,并且修改点代码:
然后启动server和client;就会发现代码停在关闭的地方:
当下一步的时候,则会来到最开始的断点:
这个时候的unsafe就是NioSocketChannel,继续跟进并在下图的“doReadBytes()”打个断点:
继续跟进:
再进入writeBytes():
这个时候writtenBytes=-1, -1表示正常关闭,然后返回-1;接着回去
进入closeOnRead();
再进入close();一直跟进后:
这里this.outboundBuffer=nul;表示不接受消息,接着往下走有个doClose0();
一直跟进去,直到看到javaChannel.close();
这个其实就是调用jdk:
再继续跟进:
就是将SelectionKey从Selector上cancel掉,这样的话这个Selector上就不会发生这个Channel的event了!接着返回
一直跟进:
点进去不妨可以看出:
它也做了一次cancel;
跳转回来一次正常的关闭就结束了
----总结:
连接关闭本质:
java.nio.channels.spi.AbstractInterruptibleChannel#close;
java.nio.channels.SelectionKey#cancel
关闭连接,会触发OP_READ方法。读取字节数是-1代表关闭
数据读取进行时,强行关闭,触发IO Exception,进而执行关闭
Channel的关闭包含了SelectKey的cancel.