原文地址 : http://blog.csdn.net/joker_zhou/article/details/7325295
非阻塞通信
对于ServerSoket及Socket编写的服务器程序和客户端程序,他们在运行过程中常会阻塞,例如:ServerSocket的accept方法和Socket得到的输入流的read方法都会在没有"数据"时阻塞.非阻塞通信有java.nio包的类实现的
Java.nio中的主要类
ServerSocketChannel:ServerSocket的替代类.
SocketChannel:Socket的替代类
Selector:为ServerSocketChannel监控接受就绪事件,为SocketChannel监控连接就绪,读就绪和写就绪事件
SelectionKey:代表ServerSocketChannel及SocketChannel向Selector注册事件句柄
向SocketChannel和ServerSocketChannel注册事件:
SelectionKey key=serverSocketChannel.register(selector,op)
Op的可选值
对于ServerSocketChannel只有一个事件:
(1)SelectionKye.OP_ACCEPT:接受连接就绪事件,表示至少有了一个客户连接,服务器可以接受这个连接
SocketChannel可能发生3种事件
(1)SelectionKey.OP_CONNECT:连接就为事件,表示客户与服务器的连接已经成功
(2)SelectionKey.OP_WRITE/OP_READ:写的就绪事件,表示已经可以向输出流写数据了SocketChannel提供了接受和发送的方法
可以使用:read(ByteBuffer)write(ByteBuffer)写入写出
SelectableChannel:
SelectableChannel是ServerSocketChannel和SocketChannel(还实现了ByteChannel类)的父类,支持阻塞IO和非阻塞IO
主要方法:
(1) SelectableChannel configureBlocking(boolean)改变阻塞模式ture时为阻塞,false为非阻塞.
(2)SelectionKeyregister(Selector,int ops)
SelectionKey register(Selector,intops,Object attachment)
向Selector注册事件
(3)validOps 返回一个此通道支持的操作集(SelectorKey的四个操作常量)
(4)isRegistered是否向此通道注册任何Selector.
ServerSocketChannel类
方法:(PS继承过SelectableChannel类的方法)
(1)open()静态方法获取ServerSocketChannel对象.
(2)accept同ServerSocket,不过获取的是SocketChannel,根据是否阻塞返回null还是阻塞,值得注意的是accept返回的SocketChannel是阻塞模式的使用configureBlocking更改模式
(3)socket() 返回关联的ServerSocket
SocketChannel类
此类是Socket类的替代类
方法:(PS继承过SelectableChannel类的方法)
(1)open() open(SocketAddress)静态方法用来创建SocketChannel对象,第二个重写还会建立于远程服务器的连接.
(2)socket()返回关联的Socket对象
(3)isConnected()是否建立连接
(4)isConnectionPending判断是否正在进行远程连接
(5)connect() 建立远程连接() 根据是否阻塞而不同
(6)finishConnect() 视图完成远程连接
(7)read()读取数据(这个应该是接数据)
(8)write()写数据(这个是发送数据)
Selector类
只要ServerSocketChannel或SocketChannel向Selector注册特定的事件,Selector会监控这些时间是否发生.SelectableChannel的register负责注册时间并且返回一个SelectionKey对象.
一个Selector有3种类型的SelectionKey集合
(1)all-key 当前所有向Selector注册的SelectionKey集合,keys()方法返回.当 register执行时,会向Selector的此集合加入一个SelectionKey.此集合不可以改变
(2)selected-keys:相关时间已经被Selector捕获的SelectionKey集合selectedKeys() 方法返回.就是注册监听的事件已经发生的事件集.此集合可以删除.
(3)cancelled-keys集合:已经被取消的SelectionKey的集合.Selector没有提供访问这 种集合的方法.当关闭与SelectionKey对象关联的Channel对象时,或者调用了 SelectionKey对象的cancel()方法时,这个SelectionKey对象会被加入到此集合中,在 程序下一次执行Selector的select()方法四,被取消的SelectionKey对象将从所有的集 合中删除
PS:这些集合不允许直接操作
Selector方法:
(1)open() 静态的open()创建一个Selector
(2)isOpen()检查Selector对象是否打开,close()方法能使其进入关闭状态
(3)keys()上面有介绍获取所有注册过的事件监听器.
(4)selectNow()返回已经发生的SelectionKey对象的数目.
(5)select(long)返回已经发生的SelectionKey数目,参数是可以阻塞延迟多少毫秒
(6)wakeup()方法会立即使调用此方法的Selector对象的select立即返回. 并且只能唤醒一次的select方法,(对于下一次调用和本次在阻塞的select 方法使用)
(7)close()关闭Select
SelectionKey类
SeletionKey是监听器类,使用SelectableChannel的register注册进Selector中.也就是Selector的3个集合中.
这里要说这4种事件可以使用 "|"来组合.
方法:
(1)channel()返回这个SelectionKey关联的SelectableChannel对象;
(2)selector() 返回SelectionKey关联的Selector对象
(3)isValid()查看此SelectionKey是否有效,失效情况:
A)调用SelectionKey的cancel方法
B)关闭与之关联的SelectableChannel 对象
C)关闭与之关联的Selector 对象
(4)cancel() 使SeletionKey对象
(5)interrestOps() 返回这个SelectionKey感兴趣的事件
(6)interestOps(int ops)添加感兴趣事件
(7)readyOps()返回已经就绪的时间.
(8)isReadable()判断与之关联的读事件是否已经就绪
(9)isWritable()写事件是否就绪
(10)isConnectable() 连接事件是否就绪
(11)isAcceptable()接受事件是否就绪
(12)attach(Object) 附加一个附件.
(13)attachment() 返回SelectionKey对象关联的附件.