莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          NIO的SelectableChannel關閉的一個問題

          Posted on 2008-06-18 01:50 dennis 閱讀(2458) 評論(2)  編輯  收藏 所屬分類: java
              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編程有很多這樣細節性的東西需要注意,通常情況下還是利用成熟的框架為妙。


          評論

          # re: NIO的SelectableChannel關閉的一個問題  回復  更多評論   

          2008-06-18 09:19 by Arbow
          這樣的分享不錯!“通常情況下還是利用成熟的框架為妙”

          # re: NIO的SelectableChannel關閉的一個問題  回復  更多評論   

          2009-07-13 18:11 by 吳冬冬
          感謝
          為這個問題煩惱了好幾天了
          我用close關閉的select 怎么也關閉不了
          主站蜘蛛池模板: 恩施市| 屏东市| 桂阳县| 永嘉县| 嘉禾县| 南汇区| 临澧县| 台州市| 阜康市| 晋城| 马龙县| 克拉玛依市| 商水县| 泽库县| 鄯善县| 霍州市| 洪洞县| 甘谷县| 鄂温| 塔城市| 刚察县| 合阳县| 永福县| 金溪县| 临颍县| 白山市| 和平区| 永仁县| 三明市| 礼泉县| 磐安县| 叙永县| 垣曲县| 南丹县| 吴忠市| 松溪县| 山东省| 贺州市| 井陉县| 宁武县| 临西县|