java NIO 实现非阻塞socket通信

java的nio为非阻塞式socket通信提供了如下几个类:

          Selector : 它是SelectableChannel对象的多路复用器,所有希望采用非阻塞方式进行通信的channel都应该注册到Selector对象。可以通过调用此类的open()静态方法来创Selector实例,该方法将使用系统默认的Selector来返回新的Selector。 

Selector可以同时监控多个SelectortableChannel的IO状况,是非阻塞IO的核心。一个Selector实例有3个SelectIonKey集合

   1.所有的SelectionKey集合:代表了注册在该Selector上的Channel,该集合可以通过keys()方法返回。

   2.被选择的SelectionKey集合 : 代表了所有可通过select()方法获取的,需要进行IO处理的Channel,这个集合可以通过selectedKeys()返回。

   3.被取消的SelectionKey集合:代表了所有被取消注册关系的Channel,在下一次执行select()方法时,这些Channel对应的SelectionKey会被彻底删除,程序通常无须直接访问该集合。

Selector还提供了一系列和select()相关的方法。

      int select() : 监控所有注册的Channel,当它们中间有需要处理的IO操作时,该方法返回,并将对应的Selection加入被选择的SelectionKey集合中,该方法返回这些Channel的数量。

      int select(long timeout) : 可以设置超时时长的select()操作

      int selectNow() : 执行一个立即返回的select()操作,相对于无参数的select()方法而言,该方法不会阻塞线程。

      Selector wakeup() : 使一个还未返回的select()方法立刻返回

SelectableChannel类提供了如下方法来设置和返回该channel的模式状态

  SelectableChannel configureBlocking(boolean block) : 设置是否采用阻塞模式

  boolean isBlocking() : 返回该channel是否是阻塞模式

  int vaildOPs() : 返回一个整数值,表示这个Channel所支持的IO操作 OP_READ(1), OP_WRITE(4),OP_CONNECT(8),OP_ACCEPT(16)

SelectableChannel还提供了如下几个方法来获取它的注册状态

  boolean isRegistered() : 返回该channel是否注册在一个或多个selector上

​  SelectionKey keyFor(Selector sel) : 返回该channel和sel Selector之间的注册关系,如果不存在注册关系,则返回null.


 

就像这个图,服务器上的所有channel都需要向Selector注册,Selector则负责监视这些socket的IO状态,当其中任意一个或者多个channel具有可用的IO操作,该Selector的select()方法将会返回大于0的整数,该整数表示该Selector上有多少个channel具有可用的IO操作,并提供了selectedKeys()方法来返回这些channel对应的SelectionKey集合。正是通过Selector,使得服务器端只需要不断的调用Selector实例的select()方法,即可知道当前的所有channel是否有需要处理的IO操作。当Selector上注册的所有channel都没有需要处理的IO操作时,select()方法将会被阻塞,调用该方法的线程被阻塞

服务器端的需要使用ServerSocketChannel来对客户端进行监听部分代码如下

 

如果需要使用非阻塞方式来处理该ServerSocketChannel,还应该设置它的非阻塞方式,并将其注册到指定的Selector,代码片段如下


 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值