Java粗淺認識-網絡編程(一)

網絡通信

網絡通信,就是進程間的一種通信方式,網絡通信都採用客戶端-服務端模型,當然與之相對的就是進程內部的通信(就是後面要講的多線程編程裏面的東西,包括同步,信號量)。

client-server模型

unix網絡通信關於網絡通信

I/O多路複用select(基於輪詢,支持少數文件描述符)、poll(基於輪詢,支撐大量文件描述符)、epoll(系統計算文件描述數量,基於回調)

select 在初始化時,指定描述符容量大小,FD_SETSIZE的值上限在不同平臺上運行是不一致的windows上是64(WINSOCK.H文件中定義)和linux(ulimit -a 查找open files 項)上受限於每個進程打開的最大文件個數(默認1024)

winsock.h文件中定義

winsock.h

linux fd限制

linux fd限制
linux open files限制


這裏的select 函數 後來有pselect函數支持納秒級別超時等待

poll 在初始化時,傳入的第一個參數是一個鏈表,表示支持的文件描述,意味着受限於內存大小

select和poll都是在每次調用監聽文件描述符時,是通過輪詢來遍歷,隨着連接數量的增加,性能會下降

epoll,基於select和poll的缺點在2.6內核中引入,epoll中epoll_create(int size)中的size不是最大值,是一個估算值,系統會動態計算出真正的值,甚至在之後的更新中,只要是個整數就行
epoll_ctl(),控制文件描述的添加、刪除,文件描述符感興趣的事件註冊和更改,就是一個回調機制。在epoll_ctl中傳入的事件event.events是一個枚舉類型,通過|符號來添加監聽事件,其中如果添加了EPOLLET,設置關聯的fd爲ET的工作方式(水平觸發事件立即返回結果)默認工作方式是LT(邊緣觸發事件,等待處理完畢後返回結果)。

I/O複用,理解I/O複用,就要理解,I/O沒有複用的情況,多個連接同時請求一個服務,服務就排隊一個一個處理,爲了解決這個問題,就提出了I/O複用,通過上面講解的select,poll,epoll 來統一接收請求,分發任務(select、poll)或主動處理,任務結束後通知(epoll回調)來解決。

網絡通信模型

單進程模式

父進程接收到請求,fork子進程來處理,處理完畢了關閉子進程,缺點是,每次都要fork新的子進程出來,開銷大

preforking改進

提前fork一個子進程池,父進程接收到請求,直接使用閒置的子進程

單線程模式

進程接收到請求,直接創建一個線程,就是每個請求,對應一個線程

prethreading改進

服務器啓動時,預先創建一個線程池,服務器接收到請求,使用閒置的線程處理,不用臨時創建新線程

Reactor,反應堆(I/O多路複用+線程池)

一個線程(進程)或線程池(進程池)每當Reactor(s)接受到一個請求時,就分配任務給其他線程或線程池處理,其中Netty採用多Reactor(接受)多線程(處理)模式

Proactor(異步網絡模型)

每個請求來時,Proactor構造器負責創建Proactor時,同時也會創建對應的Handler回調,異步處理器(內核中)把Proactor和Handler同時註冊到內核當中,異步處理器完成I/O後就會通知Proactor,proactor就會回調相應的Handler
說來比較拗口,簡單點講就是內核異步處理I/O操作,通知Proactor,proacor回調handler,linux下的異步網絡模型就通過Reactor+epoll模擬出來的。

總結,網絡編程模型講解到此結束,接下里會一一通過Java代碼展示講解單線程模型prethreadingreactorproactor

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章