•filechannel : 由上圖可知道,該channel 只有阻塞模式。•datagramchannel
•socketchannel
serversocketchannel
三個網路channel 可以通過configureblocking 方法,設定非阻塞模式
nio ,只有在 網路中,使用selector 實現多路復用,才是實現了非阻塞模式。單純的使用 buffer channel 是無法實現非阻塞的。非阻塞: 請求資源,若資源未準備好,則不等待,而是直接返回 乙個 error標識。但是為了獲取資源,我們就要不停的去請求,仍然不能實現現實的非阻塞。所以使用多路復用,當前通過乙個單獨的執行緒使用 select 去監視多個channel , 那麼只需要該執行緒不斷的去請求,看哪些channel 是準備好的。
特別注意上邊serversocketchannel , 這個channel 只有乙個,負責監聽客戶端來的連線。他監聽乙個埠。將該 serversocketchannel 要設定為非阻塞。 因為其被繫結在 select 上,server.accept(),若是阻塞的,將會造成阻塞,不能去監聽其他channel .所以 serversocketchannel 和socketchannel 地位是平等的。select 對 serversocketchannel 監聽 連線請求。有連線是, 其去新建channel 繫結為讀請求,並繫結到select.詳情看**。伺服器開啟時,只有 serversocketchannel 乙個channel繫結在select 上,當來請求時,建立新的channel,並繫結到select上去監聽讀就緒。
public class nserver
// 如果sk對應的channel有資料需要讀取
if (sk.isreadable()) // ③
// 列印從該sk對應的channel裡讀取到的資料
system.out.println("讀取的資料:" + content);
// 將sk對應的channel設定成準備下一次讀取
sk.interestops(selectionkey.op_read);
}// 如果捕捉到該sk對應的channel出現了異常,即表明該channel
// 對應的client出現了問題,所以從selector中取消sk的註冊
catch (ioexception ex)
}// 如果content的長度大於0,即聊天資訊不為空
if (content.length() > 0)}}
}}} }public static void main(string args)
throws ioexception
}
public class nclient
} // 定義讀取伺服器資料的執行緒
private class clientthread extends thread
// 列印輸出讀取的內容
system.out.println("聊天資訊:" + content);
// 為下一次讀取作準備
sk.interestops(selectionkey.op_read);}}
}}catch (ioexception ex)
}} public static void main(string args)
throws ioexception
}
非阻塞式socket
返回錯誤ewouldblock或eagain。套接字的預設狀態是阻塞的。這就意味著當發出乙個不能立即完成的套接字呼叫時,其進 程將被投入睡眠,等待相應操作完成。可能阻塞的套接字呼叫可分為以下四類 1 輸入操作,包括read readv recv recvfrom和 recvmsg共5個函式。如果某個...
阻塞IO與非阻塞NIO
通常的,對乙個檔案描述符指定的檔案或裝置,有兩種工作方式 阻塞 與非阻塞 所謂阻塞方式的意思是指,當試圖對該檔案描述符進行讀寫時,如果當時沒有東西可讀,或者暫時不可寫,程式就進入等待 狀態,直到有東西可讀或者可寫為止。而對於非阻塞狀態,如果沒有東西可讀,或者不可寫,讀寫函式馬上返回,而不會等待 一種...
Socket實現非阻塞連線
include include include include pragma comment lib,ws2 32.lib define time out time 20 connect超時時間20秒 void geturl char url socket sockfd struct sockadd...