在學習IBM的那個NIO教程時發(fā)現(xiàn),異步IO這部分的代碼居然有個嚴重問題。
即client突然中斷 tcp連接時。服務(wù)端會進入一個令人崩潰的無限循環(huán)。
后來發(fā)現(xiàn)其實是因為selector在tcp連接已經(jīng)斷開時,還是能夠select()出OP_READ狀態(tài)的SocketChannel的SelectedKey。
這時需要通過Channel讀取數(shù)據(jù)到buffer的過程時的返回值來判斷。
這個反回值其實就是讀取的字節(jié)數(shù)。該數(shù)字為0時說明就是一般的沒有數(shù)據(jù)可讀取,而當為-1時其實表示底層tcp已經(jīng)斷開了。(但IE的連接有點不同,read時直接給出Exception,反正這些情況都要判斷了.)
之后又想到,那如何注銷selector與SocketChannel之間的關(guān)聯(lián)呢?selector內(nèi)部基本的運作是怎么樣的呢? javadoc中寫的是key.cancel()方法。socket的close()在windows似乎也有一樣的功能。
這里可以用兩張圖來表示。