NIO的SelectableChannel关闭的一个问题

    SocketChannel和ServerSocketChannel,两者的父类是SelectableChannel,它在jdk中的文档有这么段话:

 

   Once registered with a selector, a channel remains registered until it is deregistered.This involves deallocating whatever resources were allocated to the channel by the selector.
    A channel cannot be deregistered directly; instead, the key representing its registration must be cancelled. Cancelling a key requests that the channel be deregistered during the selector's next selection operation.

 

    也就是说关闭一个已经注册的SelectableChannel需要两个步骤:

1)取消注册的key,这个可以通过SelectionKey.cancel方法,也可以通过SelectableChannel.close方法,或者中断阻塞在该channel上的IO操作的线程来做到。

2)后续的Selector.selectXXX方法的调用才真正地关闭 本地Socket。

    因而,如果,如果在取消SelectionKey后没有调用到selector的select方法(因为Client一般在取消key后, 我们都会终止调用select的循环,当然,server关闭一个注册的channel我们是不会终止select循环的),那么本地socket将进入CLOSE-WAIT 状态(等待本地Socket关闭)。简单的解决办法是在 SelectableChannel.close方法之后调用Selector.selectNow方法,类似:

   Selector sel;
   SocketChannel sch;
   // …
   sch.close();
   sel.selectNow();


    Nio编程有很多这样细节性的东西需要注意,通常情况下还是利用成熟的框架为妙。

你可能感兴趣的:(jdk,编程,框架,socket)