Netty的AbstractNioByteChannel源码解析

Netty的AbstractNioByteChannel源码解析教程

AbstractNioByteChannel 是 AbstractNioChannel 的子类,它的大部分功能和 AbstractNioChannel 类似,只不过单独的实现了部分功能。

成员变量

它和 AbstractNioChannel 相比,只是多了一个 Runnable 类型的 flushTask。它是用来负责继续写半包消息的。

核心方法

doWrite()源码

@Override protected void doWrite(ChannelOutboundBuffer in) throws Exception { int writeSpinCount = config().getWriteSpinCount(); do { Object msg = in.current(); if (msg == null) { // Wrote all messages. clearOpWrite(); // Directly return here so incompleteWrite(...) is not called. return; } writeSpinCount -= doWriteInternal(in, msg); } while (writeSpinCount > 0); incompleteWrite(writeSpinCount < 0); }

调用 in.current() 方法,它是从发送消息环形数组 ChannelOutboundBuffer 中获取一条数据,判断该数据是否为空,如果为空,说明消息发送数组中所有待发送的消息都已经发送完成了,清除半包标识,然后退出循环。

clearOpWrite() 方法

protected final void clearOpWrite() { final SelectionKey key = selectionKey(); // Check first if the key is still valid as it may be canceled as part of the deregistration // from the EventLoop // See https://github.com/netty/netty/issues/2104 if (!key.isValid()) { return; } final int interestOps = key.interestOps(); if ((interestOps & SelectionKey.OP_WRITE) != 0) { key.interestOps(interestOps & ~SelectionKey.OP_WRITE); } }

从当前的 SelectionKey 中获取网络操作位,然后与 SelectionKey.OP_WRITE 做按位与,如果不等于 0 ,说明当前的 SelectionKey 是 isWritable 的,需要清除写操作位。清除方法是 SelectionKey.OP_WRITE 取非之后与原操作位做按位与操作,清除 SelectionKey 的写操作位。

Netty的AbstractNioByteChannel总结

本章我们了解了 AbstractNioByteChannel 的 dowrite 大体方法,读取操作和对 Write 的判断。d