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