何为通道(Channel)?代表的是一个网络套接字的连接点(nexus)。
一个通道抽象的内容包括:
1)当前通道状态,是否打开,是否绑定等;
2)通道的配置参数信息,如套接字缓冲区大小;
3)通道支持的IO操作;
4)处理和这个Channel相关的IO事件和请求的ChannelPipeline。
在Netty中所有的IO操作都是异步的,即执行一个IO调用的时候不会阻塞到操作完成,而后立即返回一个ChannelFuture对象,这个ChannelFuture对象会在某个时候通知我们IO操作执行结果(成功,失败或取消)。
Channel是分层结构的(和传输层实现有关),比如说一个监听套接字ServerSocketChannel在接收一个连接请求后会创建一个连接套接字对应的通道SocketChannel,那么当对一个连接通道调用getParent() 的时候就会返回那个监听通道实体。
每个通道还有一个interestOps属性,和select机制类似,就是告知内核该通道感兴趣的事件,有两个比特标识构成:
OP_READ: 如果设置了这个标识,并且有对端的数据到达,那么就会进行read操作;否则即使有数据也不会读取(读悬挂),有点边沿触发的味道。
OP_WRITE: 如果设置了该位,写请求不会将数据发送给对端,而是追加到队列中,如果清楚了这个标识,写请求就会从队列中flush。
OP_READ_WRITE:只有写请求会被悬挂(suspend)。
OP_NONE : 只有读请求会被悬挂。
比如接口中setReadable这个方法可以通过设置/清除OP_READ来:Suspends
or resumes the read operation of the I/O thread asynchronously。等价代码是:
int interestOps = getInterestOps();
if (readable) {
setInterestOps(interestOps | OP_READ);
} else { // clear the flag
setInterestOps(interestOps & ~OP_READ);
}
要注意的是,不能像设置/清除OP_READ标识那样来悬挂或恢复写操作,OP_WRITE这个标识只是用来告知悬挂的写请求是否超过了一定的阈值。比如在NIO
socket中可以通过NioSocketConfig设置低水位/高水位标识。
这个接口的源码如下:
public interface Channel extends Comparable<Channel>
{
int OP_NONE =
0;
int OP_READ =
1;
int OP_WRITE =
4;
int OP_READ_WRITE = OP_READ | OP_WRITE ;
Integer getId();
ChannelFactory getFactory();
Channel getParent();
ChannelConfig getConfig();
ChannelPipeline getPipeline();
boolean isOpen();
boolean isBound();
boolean isConnected();
SocketAddress getLocalAddress();
SocketAddress getRemoteAddress();
ChannelFuture write(Object message);
ChannelFuture write(Object message, SocketAddress
remoteAddress);
ChannelFuture bind(SocketAddress localAddress);
ChannelFuture connect(SocketAddress remoteAddress);
ChannelFuture disconnect();
ChannelFuture unbind();
ChannelFuture close();
ChannelFuture getCloseFuture();
int getInterestOps();
boolean isReadable();
boolean isWritable();
ChannelFuture setInterestOps( int interestOps);
ChannelFuture setReadable( boolean readable);
Object getAttachment();
void setAttachment(Object
attachment);
}