一、 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();
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.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 的区别