转自:http://blog.csdn.net/wolfdrake/article/details/37921441
SocketChannel类(用于阻塞或非阻塞式传输数据)
创建SocketChannel要使用SocketChannel类的静态工厂方法。
SocketChannel open():创建未连接的SocketChannel.
SocketChannel open(SocketAddress remote):创建连接到remote端口的SocketChannel.
新创建的SocketChannel为阻塞式的。
SelectableChannel configureBlocking(boolean block):将本SocketChannel设置为阻塞或非阻塞式并返回。
boolean isBlocking():返回本SocketChannel是否处于阻塞模式。
boolean connect(SocketAddress remote):连接到remote端口,是否是阻塞式连接取决于SocketChannel的设置。函数返回时,若已连接成功则返回true.
boolean finishConnect(SocketAddress);非阻塞connect返回false之后,可以调用这个函数完成连接,这个函数是否阻塞取决于SocketChannel的设置。函数返回时,若已连接成功则返回true.如果在调用函数之前就已经成功连接了,则函数什么都不做,直接返回true.
boolean isConnected():SocketChannel已连接时返回true.
boolean isConnectionPending():如果SocketChannel正在尝试连接,则返回true.
Socket socket():返回此SocketChannel的socket.
int read(ByteBuffer dst):将dst从position填充至limit,读到流末尾会停下来,非阻塞读时一旦没得可读也会停下来,是否阻塞取决于SocketChannel的设置。返回实际读到的字节数n,同时dst的position会加n.如果读之前socket的输入流就位于流末尾,则返回-1.如果函数调用时已经有一个线程正在从输入流里读,则本线程会等到它读完之后才开始读。
int write(ByteBuffer src):将src从position到limit的数据写入socket的输出流,非阻塞写时一旦底层的输出缓冲区满了就会停下来,是否阻塞取决于SocketChannel的设置。返回实际写入的字节数n,同时src的position会加n.如果函数调用时已经有一个线程正在往输出流里写,则本线程会等到它写完之后才开始写。
int validOps():返回SocketChannel可能产生的事件,即SelectionKey.OP_CONNECT|SelectionKey.OP_READ|SelectionKey.OP_WRITE(连接成功、可读、可写)。
SelectionKey register(Selector sel, int ops, Object att):要求侦听者sel帮忙侦听ops事件,返回这个契约。契约可以带一个附件att,若att为null则不带附件。
SelectionKey register(Selector sel, int ops):同上,相当于att等于null,不带附件。
SelectionKey keyFor(Selector sel):返回与侦听者sel定下的契约。如果尚未定下契约,则返回null.
boolean isRegistered():如果本SocketChannel现在正和某侦听者有契约,则返回true.尚未和任何侦听者定下过契约,或全部契约都已经解除,这两种情况都返回false.
void close():关闭本SocketChannel,并解除其一切契约。
boolean isOpen():如果本SocketChannel处于打开状态,则返回true.
ServerSocketChannel类(用于阻塞或非阻塞式侦听连接)
创建ServerSocketChannel要使用ServerSocketChannel类的静态工厂方法。
ServerSocketChannel open():创建未绑定的ServerSocketChannel.
新创建的ServerSocketChannel是阻塞式的。
ServerSocket socket():返回此ServerSocketChannel的serversocket.
SocketChannel accept():侦听连接请求,阻塞模式下会一直等待直到出现请求,非阻塞模式下如果没有请求就直接返回null.
int validOps():返回ServerSocketChannel可能产生的事件,即SelectionKey.OP_ACCEPT(有连接请求)。
SelectableChannel configureBlocking(boolean block),boolean isBlocking(),SelectionKey register(Selector sel, int ops, Object att),SelectionKey register(Selector sel, int ops),SelectionKey keyFor(Selector sel),boolean isRegistered(),void close(),boolean isOpen():参见SocketChannel类的相应函数。
Selector类(侦听器类)
1. 侦听者维护三个契约集合:all-keys,selected-keys,cancelled-keys.
侦听者创建时,三个集合都是空的。每缔结一个契约,就把它添加到all-keys中。调用select或selectNow函数时会把all-keys中发生了事件的契约也添加到selected-keys中。一个契约被解除时,会被添加到cancelled-keys中,下次调用select或selectNow函数时就会从全部三个集合中被删去。可见,后两个集合始终是all-keys的子集。
2. 创建侦听器要采用Selector类的静态工厂方法。
Selector open():创建侦听器。侦听器被创建后直接就是开着的。
boolean isOpen():如果侦听器是开着的,则返回true.
Set<SelectionKey> keys():返回all-keys契约集。不得对这个集合进行修改。
Set<SelectionKey> selectedKeys():返回selected-keys契约集。对这个集合只能删除契约,不得做其它修改。
Selector wakeup():给侦听器吃“提神药”(见select函数)并返回。
int select(long timeout):将all-keys中发生了事件的契约也添加到selected-keys中,如果没有一个发生了事件,则阻塞等待,至多等待timeout毫秒,而且只要吃了提神药,就会立刻退出阻塞,并消耗掉全部的药效。最终返回添加契约的个数。如果timeout为0,则禁用超时。
可见,如果进程A阻塞于侦听器s的select函数,进程B调用s.wakeup(),则进程A立刻退出阻塞。
如果进程B调用一次或多次s.wakeup(),然后进程A调用s的select函数,则select会立即返回。接下来如果没有进程调用s.wakeup(),则再次select的话又会阻塞。
int select():同上,只不过禁用超时。
int selectNow():同样是将all-keys中发生了事件的契约也添加到selected-keys中,返回添加的个数,但是是非阻塞式的,没有就返回0.
void close():给侦听器吃提神药,解除其一切契约,然后将它关闭。
SelectionKey类(契约类)
Object attach(Object ob):设置契约的附件为ob。如果ob为null则表示不要附件。
Object attachment():返回本契约的附件。
SelectableChannel channel():返回缔结本契约的Channel.
Selector selector():返回缔结本契约的侦听者。
SelectionKey interestOps(int ops):设置侦听者所要侦听的事件,并返回本契约。SelectionKey.OP_READ,SelectionKey.OP_WRITE,SelectionKey.OP_CONNECT,SelectionKey.OP_ACCEPT,分别表示Channel的输入流有数据可读、输出流有空位可写、连接成功、有连接请求事件。多个事件用位或(|)来组合。
int interestOps():返回侦听者所要侦听的事件。
int readyOps():返回已经发生的事件。
boolean isReadable/isWritable/isConnectable/isAcceptable():如果Channel的可读/可写/连接成功/有连接请求事件已发生,则返回true.
void cancel():解除本契约。
isValid():返回本契约当前是否有效(尚未被解除)。