NIO實現非阻塞式Socket通訊

2021-08-30 08:36:48 字數 2115 閱讀 7669

•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...