随笔 - 1162  文章 - 0  评论 - 16  阅读 - 59万 

一、 SelectionKey

1、SelectionKey

SelectionKey, 表示Selector和网络通道(Channel)绑定的关系。

以 SelectorImpl 为例,看一下源码:

public abstract class SelectorImpl extends AbstractSelector {
    //当前 selector 中关注事件的 selectionKey
    protected Set<SelectionKey> selectedKeys = new HashSet();
    
    //当前 selector 中已经注册的 selectionKey
    protected HashSet<SelectionKey> keys = new HashSet();
    private Set<SelectionKey> publicKeys;
    private Set<SelectionKey> publicSelectedKeys;

...
}

2、相关API

(1)SelectionKey, 表示 Selector 和网络通道的注册关系, 共四种:

int OP_READ: 代表读操作, 值为 1

int OP_WRITE: 代表写操作, 值为 4

int OP_CONNECT: 代表连接已经建立, 值为 8

int OP_ACCEPT: 有新的网络连接可以 accept, 值为 16

源码中:

public static final int OP_READ = 1 << 0;
public static final int OP_WRITE = 1 << 2;
public static final int OP_CONNECT = 1 << 3;
public static final int OP_ACCEPT = 1 << 4;

(2)SelectionKey相关方法

public abstract class SelectionKey {

    protected SelectionKey() { }

    // -- Channel and selector operations -- 通道和选择器操作
    //得到与之关联的通道
    public abstract SelectableChannel channel();

    //得到与之关联的Selector 对象
    public abstract Selector selector();

    public abstract boolean isValid();

    public abstract void cancel();


    // -- Operation-set accessors -- 操作集访问器
    public abstract int interestOps();

    //设置或改变监听事件
    public abstract SelectionKey interestOps(int ops);

    public abstract int readyOps();

    // -- Operation bits and bit-testing convenience methods -- 
    //操作位和位测试便利方法
    public static final int OP_READ = 1 << 0;
    public static final int OP_WRITE = 1 << 2;
    public static final int OP_CONNECT = 1 << 3;
    public static final int OP_ACCEPT = 1 << 4;

    //是否可以读
    public final boolean isReadable() {
        return (readyOps() & OP_READ) != 0;
    }

    //是否可以写
    public final boolean isWritable() {
        return (readyOps() & OP_WRITE) != 0;
    }

    public final boolean isConnectable() {
        return (readyOps() & OP_CONNECT) != 0;
    }

    //是否可以 accept
    public final boolean isAcceptable() {
        return (readyOps() & OP_ACCEPT) != 0;
    }


    // -- Attachments -- 附件

    private volatile Object attachment = null;

    private static final AtomicReferenceFieldUpdater<SelectionKey,Object>
        attachmentUpdater = AtomicReferenceFieldUpdater.newUpdater(
            SelectionKey.class, Object.class"attachment"
        );

    //得到与之关联的共享数据
    public final Object attach(Object ob) {
        return attachmentUpdater.getAndSet(this, ob);
    }

    public final Object attachment() {
        return attachment;
    }

二、 ServerSocketChannel

1、ServerSocketChannel

  ServerSocketChannel 在服务器端监听新的客户端 Socket 连接,用于建立与客户端的连接

2、相关 API

public abstract class ServerSocketChannel 
extends AbstractSelectableChannel implements NetworkChannel
{
    protected ServerSocketChannel(SelectorProvider provider) {
        super(provider);
    }

    //得到一个 ServerSocketChannel 通道
    public static ServerSocketChannel open() throws IOException {
        return SelectorProvider.provider().openServerSocketChannel();
    }
    
    public final int validOps() {
        return SelectionKey.OP_ACCEPT;
    }
    
    // -- ServerSocket-specific operations --特定于 ServerSocket 的操作
    //设置服务器端端口号
    public final ServerSocketChannel bind(SocketAddress local) throws IOException
    {
        return bind(local, 0);
    }
    
    public abstract ServerSocketChannel bind(SocketAddress local, int backlog) throws IOException;
    
    
    public abstract <T> ServerSocketChannel setOption(SocketOption<T> name, T value) throws IOException;
    
    public abstract ServerSocket socket();
    
    //接受一个连接, 返回代表这个连接的通道对象
    public abstract SocketChannel accept() throws IOException;
    public abstract SocketAddress getLocalAddress() throws IOException;
    
    //设置阻塞或非阻塞模式, 取值 false 表示采用非阻塞模式
    public final SelectableChannel configureBlocking(boolean block);
    
    //注册一个选择器并设置监听事件
    public final SelectionKey register(Selector sel, int ops); 
    
}

三、 SocketChannel

1、SocketChannel

  SocketChannel,网络 IO 通道,具体负责进行读写操作。 NIO 把缓冲区的数据写入通道,或者把通道里的数据读到缓冲区。

2、相关 API

public abstract class SocketChannel extends AbstractSelectableChannel implements 
ByteChannel, ScatteringByteChannel, GatheringByteChannel, NetworkChannel
{

    protected SocketChannel(SelectorProvider provider) {
        super(provider);
    }
    
    //得到一个 SocketChannel 通道
    public static SocketChannel open() throws IOException {
        return SelectorProvider.provider().openSocketChannel();
    }
    
    //设置阻塞或非阻塞模式, 取值 false 表示采用非阻塞模式
    public final SelectableChannel configureBlocking(boolean block);
    
    //连接服务器
    public abstract boolean connect(SocketAddress remote) throws IOException;
    
    //如果上面的方法连接失败, 接下来就要通过该方法完成连接操作
    public abstract boolean finishConnect() throws IOException;
    
    //往通道里写数据
    public int write(ByteBuffer src);
    
    //从通道里读数据
    public int read(ByteBuffer dst);

    //注册一个选择器并设置监听事件, 最后一个参数可以设置共享数据
    public final SelectionKey register(Selector sel, int ops, Object att);
    
    //关闭通道
    public final void close();
}

 

posted on   格物致知_Tony  阅读(154)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· 面试官:你是如何进行SQL调优的?
历史上的今天:
2021-03-06 Java 常用类——String类
2021-03-06 第四节:职责链模式——总结
2021-03-06 第三节:职责链模式——在SpringMVC源码分析
2021-03-06 第二节:职责链模式——基本介绍&应用
2021-03-06 第一节:职责链模式——需求说明&传统实现
2020-03-06 URI、URL 和 URN 的区别
点击右上角即可分享
微信分享提示

目录导航