一.Channel
public interface Channel extends Closeable {
//判断此通道是否处于打开状态
public boolean isOpen();
//关闭此通道
public void close() throws IOException;
}
四个主要的实现类:
1.SocketChannel,客户端发起TCP的Channel
//客户端通道,主要两种方式可以创建SocketChannel,一种是打开一个SocketChannel并且连接到某台服务器,另外一种是一个新连接到达ServerSocketChannel时,会创建一个SocketChannel
public abstract class SocketChannel
extends AbstractSelectableChannel
implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, NetworkChannel
{
protected SocketChannel(SelectorProvider provider) {
super(provider);
}
//打开SocketChannel
public static SocketChannel open() throws IOException {
//通过SelectorProvider来创建一个SocketChannelImpl
return SelectorProvider.provider().openSocketChannel();
}
//连接到某台服务器来创建SocketChannel
public static SocketChannel open(SocketAddress remote)
throws IOException
{
SocketChannel sc = open();
try {
//连接远程地址
sc.connect(remote);
} catch (Throwable x) {
try {
//关闭channel
sc.close();
} catch (Throwable suppressed) {
x.addSuppressed(suppressed);
}
throw x;
}
//断言是否已经连接
assert sc.isConnected();
return sc;
}
//返回参数的或集
public final int validOps() {
return (SelectionKey.OP_READ
| SelectionKey.OP_WRITE
| SelectionKey.OP_CONNECT);
}
@Override
public abstract SocketChannel bind(SocketAddress local)
throws IOException;
@Override
public abstract <T> SocketChannel setOption(SocketOption<T> name, T value)
throws IOException;
public abstract SocketChannel shutdownInput() throws IOException;
public abstract SocketChannel shutdownOutput() throws IOException;
public abstract Socket socket();
public abstract boolean isConnected();
public abstract boolean isConnectionPending();
//连接远程地址
public abstract boolean connect(SocketAddress remote) throws IOException;
//判断是否已经结束连接
public abstract boolean finishConnect() throws Exception;
//得到连接的远程地址
public abstract SocketAddress getRemoteAddress() throws IOException;
//从channel中读数据到ByteBuffer
public abstract int read(ByteBuffer dst) throws IOException;
public abstract long read(ByteBuffer[] dsts, int offset, int length)
throws IOException;
public final long read(ByteBuffer[] dsts) throws IOException {
return read(dsts, 0, dsts.length);
}
//将ByteBuffer中的内容写入channel
public abstract int write(ByteBuffer src) throws IOException;
public abstract long write(ByteBuffer[] srcs, int offset, int length)
throws IOException;
public final long write(ByteBuffer[] srcs) throws IOException {
return write(srcs, 0, srcs.length);
}
@Override
public abstract SocketAddress getLocalAddress() throws IOException;
}
2.ServerSocketChannel 服务端用来监听新连接TCP的Channel,每个新进来的连接都会创建一个SocketChannel
public abstract class ServerSocketChannel
extends AbstractSelectableChannel
implements NetworkChannel
{
protected ServerSocketChannel(SelectorProvider provider) {
super(provider);
}
//通过provider来创建一个ServerSocketChannel
public static ServerSocketChannel open() throws IOException {
return SelectorProvider.provider().openServerSocketChannel();
}
//返回当前通道允许的有效操作参数集
public final int validOps() {
return SelectionKey.OP_ACCEPT;
}
//绑定监听端口
public final ServerSocketChannel bind(SocketAddress local)
throws IOException
{
return bind(local, 0);
}
//绑定监听端口
public abstract ServerSocketChannel bind(SocketAddress local, int backlog)
throws IOException;
//设置指定的socket配置参数
public abstract <T> ServerSocketChannel setOption(SocketOption<T> name, T value)
throws IOException;
//返回当前适配成的serverSocket
public abstract ServerSocket socket();
//给监听到的端口创建socketChannel
public abstract SocketChannel accept() throws IOException;
//得到绑定的当地地址
@Override
public abstract SocketAddress getLocalAddress() throws IOException;
}
DatagramChannel 通过UDP读写数据
FileChannel 在文件中读写数据
二.Buffer
public abstract class Buffer {
//可分割的迭代器的参数(有确定的大小,子迭代器都有确定的大小,元素是有序的)
static final int SPLITERATOR_CHARACTERISTICS =
Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
// Invariants: mark <= position <= limit <= capacity
//记录当前的position,通过reset可以恢复
private int mark = -1;
//位置属性
private int position = 0;
//buffer实例数据大小
private int limit;
//容量,buffer所能容纳的数据元素的最大值,被创建的时候这个值就会被赋值
private int capacity;
//缓冲区的绝对起始位置,用于unsafe类访问堆缓冲区或者访问直接缓冲区
long address;
//
Buffer(int mark, int pos, int lim, int cap) { // package-private
if (cap < 0)
throw new IllegalArgumentException("Negative capacity: " + cap);
//设置容量
this.capacity = cap;
limit(lim);
position(pos);
if (mark >= 0) {
if (mark > pos)
throw new IllegalArgumentException("mark > position: ("
+ mark + " > " + pos + ")");
this.mark = mark;
}
}
public final int capacity() {
return capacity;
}
public final int position() {
return position;
}
//设置缓冲区游标的位置
public final Buffer position(int newPosition) {
if ((newPosition > limit) || (newPosition < 0))
throw new IllegalArgumentException();
position = newPosition;
if (mark > position) mark = -1;
return this;
}
public final int limit() {
return limit;
}
//设置缓冲区的限制
public final Buffer limit(int newLimit) {
if ((newLimit > capacity) || (newLimit < 0))
throw new IllegalArgumentException();
limit = newLimit;
if (position > limit) position = limit;
if (mark > limit) mark = -1;
return this;
}
//在当前游标位置做一个标记
public final Buffer mark() {
mark = position;
return this;
}
public final Buffer reset() {
int m = mark;
if (m < 0)
throw new InvalidMarkException();
position = m;
return this;
}
//清空缓冲区
public final Buffer clear() {
position = 0;
limit = capacity;
mark = -1;
return this;
}
//翻转缓冲区,写缓冲区变成读缓冲区
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
//将游标请0,并且将标记取消
public final Buffer rewind() {
position = 0;
mark = -1;
return this;
}
//剩余可以读或写的空间
public final int remaining() {
return limit - position;
}
public final boolean hasRemaining() {
return position < limit;
}
public abstract boolean isReadOnly();
public abstract boolean hasArray();
public abstract Object array();
public abstract int arrayOffset();
public abstract boolean isDirect();
//返回当前的游标位置,并且将游标递增
final int nextGetIndex() { // package-private
if (position >= limit)
throw new BufferUnderflowException();
return position++;
}
//返回当前的游标位置,并且将游标递增n位
final int nextGetIndex(int nb) { // package-private
if (limit - position < nb)
throw new BufferUnderflowException();
int p = position;
position += nb;
return p;
}
final int nextPutIndex() { // package-private
if (position >= limit)
throw new BufferOverflowException();
return position++;
}
final int nextPutIndex(int nb) { // package-private
if (limit - position < nb)
throw new BufferOverflowException();
int p = position;
position += nb;
return p;
}
//检查参数是否在可读或者可写范围之内
final int checkIndex(int i) { // package-private
if ((i < 0) || (i >= limit))
throw new IndexOutOfBoundsException();
return i;
}
final int checkIndex(int i, int nb) { // package-private
if ((i < 0) || (nb > limit - i))
throw new IndexOutOfBoundsException();
return i;
}
final int markValue() { // package-private
return mark;
}
//将缓冲区取消
final void truncate() { // package-private
mark = -1;
position = 0;
limit = 0;
capacity = 0;
}
//废弃标记
final void discardMark() { // package-private
mark = -1;
}
//保证off+len<=size
static void checkBounds(int off, int len, int size) { // package-private
if ((off | len | (off + len) | (size - (off + len))) < 0)
throw new IndexOutOfBoundsException();
}
}
ByteBuffer 向Buffer写入数据
public abstract class ByteBuffer
extends Buffer
implements Comparable<ByteBuffer>
{
//只有缓冲区保存在堆内存中才用数组表示
final byte[] hb;
//寻址偏移值
final int offset;
boolean isReadOnly;
ByteBuffer(int mark, int pos, int lim, int cap, // package-private
byte[] hb, int offset)
{
super(mark, pos, lim, cap);
this.hb = hb;
this.offset = offset;
}
ByteBuffer(int mark, int pos, int lim, int cap) { // package-private
this(mark, pos, lim, cap, null, 0);
}
//创造直接内存缓冲区DirectByteBuffer
public static ByteBuffer allocateDirect(int capacity) {
return new DirectByteBuffer(capacity);
}
//指定capacity来创建堆内存缓冲区HeapByteBuffer
public static ByteBuffer allocate(int capacity) {
if (capacity < 0)
throw new IllegalArgumentException();
return new HeapByteBuffer(capacity, capacity);
}
//包装一个字节数组到堆内存缓冲区
public static ByteBuffer wrap(byte[] array,
int offset, int length)
{
try {
return new HeapByteBuffer(array, offset, length);
} catch (IllegalArgumentException x) {
throw new IndexOutOfBoundsException();
}
}
public static ByteBuffer wrap(byte[] array) {
return wrap(array, 0, array.length);
}
//截取旧缓冲区的活跃区域到新缓存区
public abstract ByteBuffer slice();
public abstract ByteBuffer duplicate();
public abstract ByteBuffer asReadOnlyBuffer();
public abstract byte get();
//向Buffer写入数据
public abstract ByteBuffer put(byte b);
public abstract byte get(int index);
//写入byte数组
public abstract ByteBuffer put(int index, byte b);
//从buffer中读取数据
public ByteBuffer get(byte[] dst, int offset, int length) {
checkBounds(offset, length, dst.length);
if (length > remaining())
throw new BufferUnderflowException();
int end = offset + length;
for (int i = offset; i < end; i++)
dst[i] = get();
return this;
}
public ByteBuffer get(byte[] dst) {
return get(dst, 0, dst.length);
}
public ByteBuffer put(ByteBuffer src) {
if (src == this)
throw new IllegalArgumentException();
if (isReadOnly())
throw new ReadOnlyBufferException();
int n = src.remaining();
if (n > remaining())
throw new BufferOverflowException();
for (int i = 0; i < n; i++)
put(src.get());
return this;
}
public ByteBuffer put(byte[] src, int offset, int length) {
checkBounds(offset, length, src.length);
if (length > remaining())
throw new BufferOverflowException();
int end = offset + length;
for (int i = offset; i < end; i++)
this.put(src[i]);
return this;
}
public final ByteBuffer put(byte[] src) {
return put(src, 0, src.length);
}
public final boolean hasArray() {
return (hb != null) && !isReadOnly;
}
public final byte[] array() {
if (hb == null)
throw new UnsupportedOperationException();
if (isReadOnly)
throw new ReadOnlyBufferException();
return hb;
}
//返回数组偏移量(堆内存)
public final int arrayOffset() {
if (hb == null)
throw new UnsupportedOperationException();
if (isReadOnly)
throw new ReadOnlyBufferException();
return offset;
}
//压缩缓存区,将没有读完的数据挪到容器起始处
public abstract ByteBuffer compact();
public abstract boolean isDirect();
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getClass().getName());
sb.append("[pos=");
sb.append(position());
sb.append(" lim=");
sb.append(limit());
sb.append(" cap=");
sb.append(capacity());
sb.append("]");
return sb.toString();
}
public int hashCode() {
int h = 1;
int p = position();
for (int i = limit() - 1; i >= p; i--)
h = 31 * h + (int)get(i);
return h;
}
public boolean equals(Object ob) {
if (this == ob)
return true;
if (!(ob instanceof ByteBuffer))
return false;
ByteBuffer that = (ByteBuffer)ob;
if (this.remaining() != that.remaining())
return false;
int p = this.position();
for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
if (!equals(this.get(i), that.get(j)))
return false;
return true;
}
private static boolean equals(byte x, byte y) {
return x == y;
}
public int compareTo(ByteBuffer that) {
int n = this.position() + Math.min(this.remaining(), that.remaining());
for (int i = this.position(), j = that.position(); i < n; i++, j++) {
int cmp = compare(this.get(i), that.get(j));
if (cmp != 0)
return cmp;
}
return this.remaining() - that.remaining();
}
private static int compare(byte x, byte y) {
return Byte.compare(x, y);
}
//是否是大端法储存
boolean bigEndian // package-private
= true;
//是否与本地的字序相同
boolean nativeByteOrder // package-private
= (Bits.byteOrder() == ByteOrder.BIG_ENDIAN);
public final ByteOrder order() {
return bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
}
public final ByteBuffer order(ByteOrder bo) {
bigEndian = (bo == ByteOrder.BIG_ENDIAN);
nativeByteOrder =
(bigEndian == (Bits.byteOrder() == ByteOrder.BIG_ENDIAN));
return this;
}
abstract byte _get(int i); // package-private
abstract void _put(int i, byte b); // package-private
//一次读2个字节,按char解析,并且将position增加两个单位
public abstract char getChar();
public abstract ByteBuffer putChar(char value);
public abstract char getChar(int index);
public abstract ByteBuffer putChar(int index, char value);
public abstract CharBuffer asCharBuffer();
public abstract short getShort();
public abstract ByteBuffer putShort(short value);
public abstract short getShort(int index);
public abstract ByteBuffer putShort(int index, short value);
public abstract ShortBuffer asShortBuffer();
public abstract int getInt();
public abstract ByteBuffer putInt(int value);
public abstract int getInt(int index);
public abstract ByteBuffer putInt(int index, int value);
public abstract IntBuffer asIntBuffer();
public abstract long getLong();
public abstract ByteBuffer putLong(long value);
public abstract long getLong(int index);
public abstract ByteBuffer putLong(int index, long value);
public abstract LongBuffer asLongBuffer();
public abstract float getFloat();
public abstract ByteBuffer putFloat(float value);
public abstract float getFloat(int index);
public abstract ByteBuffer putFloat(int index, float value);
public abstract FloatBuffer asFloatBuffer();
public abstract double getDouble();
public abstract ByteBuffer putDouble(double value);
public abstract double getDouble(int index);
public abstract ByteBuffer putDouble(int index, double value);
public abstract DoubleBuffer asDoubleBuffer();
}
三.Selector
public abstract class Selector implements Closeable {
protected Selector() { }
//开启Selector
public static Selector open() throws IOException {
return SelectorProvider.provider().openSelector();
}
//判断selector是否开启
public abstract boolean isOpen();
//返回selectorProvider
public abstract SelectorProvider provider();
public abstract Set<SelectionKey> keys();
//返回响应到的key
public abstract Set<SelectionKey> selectedKeys();
//立刻返回数量不阻塞
public abstract int selectNow() throws IOException;
//在基础上增加超时机制
public abstract int select(long timeout)
throws IOException;
//阻塞到至少有一个Channel在事件上就绪了
public abstract int select() throws IOException;
public abstract Selector wakeup();
public abstract void close() throws IOException;
}
SelectionKey类
public abstract class SelectionKey {
protected SelectionKey() { }
public abstract SelectableChannel channel();
public abstract Selector selector();
public abstract boolean isValid();
public abstract void cancel();
public abstract int interestOps();
public abstract SelectionKey interestOps(int ops);
//返回当前选择键是否有效
public abstract int readyOps();
//读Key
public static final int OP_READ = 1 << 0;
//写Key
public static final int OP_WRITE = 1 << 2;
//连接Key
public static final int OP_CONNECT = 1 << 3;
//接受Key
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;
}
public final boolean isAcceptable() {
return (readyOps() & OP_ACCEPT) != 0;
}
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;
}
}