Netty3 源码分析 - Channel

来源:互联网 发布:喜购和淘宝联盟哪个好 编辑:程序博客网 时间:2024/05/04 21:46
Netty3 源码分析 - Channel

何为通道(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);
}

0 0