ServerSocketChannel、SocketChannel、Selector等概念04

java.nio包中的主要类
ServerSocketChannel:ServerSocket的替代类,支持阻塞通信与非阻塞通信。
SocketChannel:Socket的替代类,支持阻塞通信与非阻塞通信。
Selector:为ServerSocketChannel监控接收连接的就绪事件,为SocketChannel监控连接就绪、读就绪或写就绪事件。
SelectionKey:代表ServerSocketChannel及SocketChannel向Selector注册事件的句柄。当一个SelectionKey对象位于Selector对象的Selected-keys集合中时,就表示与这个SelectionKey对象相关的事件发生了。
ServerSocketChannel及SocketChannel都是SelectabletChannel的子类。SelectabletChannel类及其子类都能委托Selector来监控他们可能发生的一些事件。这种委托过程也称为注册事件过程。
ServerSocketChannel向Selector注册接收连接就绪事件:
SelctionKey key = serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);
SocketChannel可能发生以下3钟事件:
SelectionKey.OP_CONNECT:连接就绪事件
SelectionKey.OP_READ:读就绪事件,表示输入流中已经有了可读数据
SelectionKey.OP_WRITE:写就绪事件,表示已经可以向输出流写数据了。
SocketChannel提供了接收和发送数据的方法
read(ByteBuffer buffer):接收数据,把他们存放到参数指定的ByteBuffer中。
write(ByteBuffer buffer):把参数指定的ByteBuffer中的数据发送出去。
ByteBuffer表示字节缓冲区,ByteBuffer继承于Buffer类。ByteBuffer存放字节,为了把他们转换为字符串,还需要用到Charset类,Charset类代表字符编码,它提供了把字节流转换为字符串(解码过程)和把字符串转换为字节流(编码过程)的实用方法。
-----
Charset类提供了编码与解码方法:
ByteBuffer encode(String str):对参数str指定的字符串进行编码,把得到的字节序列存放在一个ByteBuffer对象中,并将其返回。
ByteBuffer encode(CharBuffr cb):字符到字节(编码)
CharBuffer decode(ByteBuffer bb):字节到字符(解码)
Charset类的静态forName(String encode)方法返回一个Charset对象,
Charset charset = Charset.forName("GBK");
--------
ServerSocketChannel类
ServerSocketChannel ssc = ServerSocketChannel.open();
这个方法没有与任何本地端口绑定,并且处于阻塞模式;
SocketChannel sc = ssc.accept();用于接收客户连接,如果ServerSocketChannel处于非阻塞模式,当没有客户连接时,该方法立即返回null.返回的SocketChannel是阻塞的,要设置非阻塞需要socketChannel.configureBlocking(false);[p/95页详细信息】
-------
Selector类:
只要ServerSocketChannel及SocketChannel向Selector注册了特定的事件,Selector就会监控这些事件是否发送。SelectableChannel的register()方法负责注册事件,该方法返回一个SelectionKey对象,该对象是用于跟踪这些注册事件的句柄。一个Selector对象中会包含3中类型的SelectionKey集合。
1、all-keys集合:当前所有想Selector注册的SelectionKey集合,Selector的keys方法返回该集合。
2、selected-key集合:相关事件已经被Selector捕获的SelectionKey的集合。Selector的selectedKeys()方法返回该集合。
3、cancelled-keys集合:已经被取消的SelectionKey的结合。Selector没有提供访问这种集合的方法。
当执行SelectableChannel的register()方法时,该方法新建一个SelectionKey,并把它加入Selector的all-keys集合中。
如果关闭了与SelectionKey对象关联的Channel对象,或者调用了SelectionKey对象的cancel()方法,这个SelectionKey对象就会被加入cancelled-keys集合中,表示这个SelectionKey对象已经被取消,在程序下一次执行的Seelector的select()方法时,被取消的SelectionKey对象将从所有的集合中删除。
在执行Selector的select()方法时,如果与SelecitonKey相关的事件发生了,这个SeletionKey就被加入到selected-keys集合中。程序直接调用selected-keys集合的remove()方法,或者调用它的Itertor的remove()方法,都可以从selected-keys集合中删除一个SelectionKey对象。
Selector主要的方法:
public static Selector open();创建一个Selector对象;
public boolean isOpen();Selector对象创建好了就处于打开状态
public Set<SelectionKey> keys()返回Selector的all-keys集合,它包含了所有与Selector关联的SelectiOnKey对象。
public int selectNow();返回相关事件已经发生的SelectionKey对象的数目。
public int select();
public Selector wakeup();唤醒执行Seletor的方法的线程。
------------
SelctionKey类
SeverSocketChannel或Socket类通过register()方法向Selector注册事件时,register()方法会创建一个SelectionKey对象,这个SelectionKey对象是用来跟踪注册事件的句柄。在SelectionKey对象的有效时间,Selector会一直监控与SelectionKey对象相关的事件,如果事件发生,就会把SelectionKey对象加入seleected-keys集合中。以下情况下SelectionKey对象会失效。
1、程序调用了SelectionKey的cancel()方法。
2、关闭与SelectionKey关联的Channel
3、与SelectionKey的Selector被关闭。
在SelectionKey中定义了4中事件:
SelecitonKey.OP_ACCEPT:接收连接就绪事件,表示服务器监听到了客户连接,服务器可以接收这个链接了。常量值为16。
SelectionKey.OP_CONNECT:连接就绪事件,表示客户与服务器的连接已经建成功了。常量值为8.
SelectionKey.OP_READ:读就绪事件,表示通道中已经有了可读数据,可以执行读操作了。常量值为1.
SelecitonKey.OP_WRITE:写就绪事件,表示已经可以向通道写数据了。常量值为4.
返回值为SelecitonKey.OP_WRITE|SelectionKey.OP_READ就表示这个SelectionKey对读就绪和写就绪事件感兴趣。与之关联的Selector对象会负责监控这些事件。当通过SelectableChannel的register()方法注册事件时,可以在参数中指定SelectionKey感兴趣的事件。
SelectionKey = key socketChannel.register(selector,SelecitonKey.OP_WRITE|SelectionKey.OP_READ);
SelecitonKey的interestOps(int ops)方法用于为SelectionKey对象增加一个感兴趣的事件。
key.interestOps(SelecitonKey.OP_WRITE);
所有已经发生的事件:SelectionKey的readyOps()方法返回所有已经发生的事件。例如,假如返回值为SelecitonKey.OP_WRITE|SelectionKey.OP_READ。表示读就绪和写就绪事件已经发生了,这就意味着与之关联的SocketChannel对象可以进行读操作和写操作了。
当程序调用了一个SelectableChannel的register(selector,xxx)方法,该方法建立了SelectableChannel对象、Selector对象以及register()方法所创建的SelecitonKey对象之间的管理关系。
SelectionKey主要方法:
public SelectableChannel channel():返回与这个SelectionKey对象关联的SelectableChannel对象。
public Selector selector():返回与这个SelectionKey对象关联的Selector对象。
public boolean isValid()判断这个SelectionKey是否有效。
public void cancel();使这个SelectionKey对象失效。
public int interestOps()返回这个SelectionKey感兴趣的事件。
public int interestOps(int ops),增加感兴趣事件
public int readyOps():返回已经就绪的事件
public final boolean isReadable();判断与之关联的SocketChannel的读就绪事件是否已经发生。该方法等价于:key.readyOps()&&OP_READ !=0
public final boolean isWritable()
public final boolean isConnectAble();
public final boolean isAcceptable();
public final Object attach(Object obj)使SelecitonKey关联一个附件。
public final Object attachment():返回SelecitonKey对象关联的附件。

猜你喜欢

转载自www.cnblogs.com/lazyli/p/10786889.html
今日推荐