AbstractNioByteChannel 是 AbstractNioChannel 的子类,它的大部分功能和 AbstractNioChannel 类似,只不过单独的实现了部分功能。
它和 AbstractNioChannel 相比,只是多了一个 Runnable 类型的 flushTask。它是用来负责继续写半包消息的。
@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 的写操作位。
本章我们了解了 AbstractNioByteChannel 的 dowrite 大体方法,读取操作和对 Write 的判断。d