前言:
前一篇中我们介绍了NioServerSocketChannel,NioServerSocketChannel主要负责两件事:绑定(bind)到本地port,作为一个Endpoint;监听客户端连接事件,将获取到的连接注册到EventLoop中。
那么数据的读写呢?NioServerSocketChannel不负责数据的读写,那么数据读写都交由NioSocketChannel来负责。
本文主要讲解NioSocketChannel 处理连接(connect)、读(read)事件。
1.NioSocketChannel类结构图同样,直接开启Diagrams视角。
与前面NioServerSocketChannel有很多相同的接口和抽象类,AbstractChannel、AbstractNioChannel、SocketChannel等前一篇文章中,都已经有说明,本文不再赘述。
2.AbstractNioByteChannel解析public abstract class AbstractNioByteChannel extends AbstractNioChannel {
// 构造方法,OP_READ代表NioSocketChannel关注的事件,在注册EventLoop时会将监听事件也传入
protected AbstractNioByteChannel(Channel parent, SelectableChannel ch) {
super(parent, ch, SelectionKey.OP_READ);
}
// 同之前的分析一样,都包含一个NioByteUnsafe
protected class NioByteUnsafe extends AbstractNioUnsafe {
// 读取对端传入的数据
@Override
public final void read() {
final ChannelConfig config = config();
// 如果输入流已经关闭,则移除OP_READ监听
if (shouldBreakReadReady(config)) {
clearReadPending();
return;
}
final ChannelPipeline pipeline = pipeline();
final ByteBufAllocator allocator = config.getAllocator();
final RecvByteBufAllocator.Handle allocHandle = recvBufAllocHandle();
allocHandle.reset(config);
ByteBuf byteBuf = null;
boolean close = false;
try {
do {
// 从ByteBufAllocator分配器中获取ByteBuf
byteBuf = allocHandle.allocate(allocator);
// doReadBytes()方法负责从channel中读取数据,交由子类NioSocketChannel实现
allocHandle.lastBytesRead(doReadBytes(byteBuf));
if (allocHandle.lastBytesRead()
关注
打赏