NIO组件源码解析

一.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;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值