六種Socket I/O模型幽默講解

老陳有一個在外地工做的女兒,不能常常回來,老陳和她經過信件聯繫。他們的信會被郵遞員投遞到他們的信箱裏。html

這和Socket模型很是相似。下面就以此爲例講解Socket I/O模型。數組

零:阻塞模型

老陳很是想看女兒的信,以致於他什麼都不作,就站在門口等。直到接到郵遞員給他的信件纔開心的看信回信。服務器

這就是阻塞模型,進程阻塞在socket的接收函數上。網絡

 

一:select模型

可是不吃不喝一直站門口等着總不行吧。因此他每隔10分鐘就下樓檢查信箱,看是否有女兒的信 。數據結構

在這種狀況下,「下樓檢查信箱「 而後回到樓上耽誤了老陳太多的時間,以致於老陳沒法作其餘工做。多線程

select模型和老陳的這種狀況很是類似:周而復始地去檢查…… 若是有數據……接收/發送 …….併發

服務器的幾個主要動做以下:app

  1. 建立監聽套接字,綁定,監聽;
  2. 建立工做者線程;
  3. 建立一個套接字數組,用來存放當前全部活動的客戶端套接字,每accept一個鏈接就更新一次數組;
  4. 接受客戶端的鏈接。

 

二:WSAAsyncSelect 異步選擇模型

後來,老陳使用了微軟公司的新式信箱。這種信箱很是先進,一旦信箱裏有新的信件,蓋茨就會給老陳打電話:喂,大爺,你有新的信件了!今後,老陳不再必頻繁上下樓檢查信箱了,牙也不疼了,你瞅準了,藍天 ……不是,微軟~~~~~~~~
微軟提供的WSAAsyncSelect模型就是這個意思。異步

WSAAsyncSelect模型是Windows 下最簡單易用的一種Socket I/O模型。使用這種模型時,Windows會把網絡事件以消息的形式通知應用程序。socket

服務器的幾個主要動做以下:

  1. 在WM_CREATE消息處理函數中,初始化Windows Socket library,建立監聽套接字,綁定,監聽,而且調用WSAAsyncSelect函數表示咱們關心在監聽套接字上發生的FD_ACCEPT事件;
  2. 自定義一個消息WM_SOCKET,一旦在咱們所關心的套接字(監聽套接字和客戶端套接字)上發生了某個事件,系統就會調用WndProc而且message參數被設置爲WM_SOCKET;
  3. 在WM_SOCKET的消息處理函數中,分別對FD_ACCEPT、FD_READ和FD_CLOSE事件進行處理;
  4. 在窗口銷燬消息(WM_DESTROY)的處理函數中,咱們關閉監聽套接字,清除Windows Socket library

特色:須要創建一個窗口用於接收消息。

 

三:WSAEventSelect 模型

後來,微軟的信箱很是暢銷,購買微軟信箱的人以百萬計數……以致於蓋茨天天 24小時給客戶打電話,累得腰痠背痛,喝蟻力神都很差使~~~~~~
微軟改進了他們的信箱:在客戶的家中添加一個附加裝置,這個裝置會監視客戶的信箱,每當新的信件來臨,此裝置會發出 「新信件到達」聲,提醒老陳去收信。蓋茨終於能夠睡覺了。

服務器的幾個主要動做以下:

  1. 感興趣的一組網絡事件建立一個事件對象,再調用WSAEventSelect函數將網絡事件和事件對象關聯起來。
  2. 當網絡事件發生時,winsock使響應的事件對象受信,在事件對象上等待的函數就會當即返回。
  3. 調用WSAEnumNetworkEvents函數即可得到到底發生了什麼網絡事件(FD_READ/FD_ACCEPT/FD_CLOSE等等)。

特色:最多能夠支持WSA_MAXIMUM_WAIT_EVENTS個對象,他的大小是64。

 

四:Overlapped I/O 事件通知模型

後 來,微軟經過調查發現,老陳不喜歡上下樓收發信件,由於上下樓其實很浪費時間。因而微軟再次改進他們的信箱。新式的信箱採用了更爲先進的技術,只要用戶告訴微軟本身的家在幾樓幾號,新式信箱會把信件直接傳送到用戶的家中,而後告訴用戶,你的信件已經放到你的家中了!老陳很高興,由於他沒必要再親自收發信件 了!

Overlapped I/O 事件通知模型和WSAEventSelect模型在實現上很是類似,主要區別在」Overlapped」,Overlapped 模型是讓應用程序使用重疊數據結構(WSAOVERLAPPED),一次投遞一個或多個 Winsock I/O請求。這些提交的請求完成後,應用程序會收到通知。什麼意思呢?就是說,若是你想從 socket上接收數據,只須要告訴系統,由系統爲你接收數據,而你須要作的只是爲系統提供一個緩衝區 ~~~~~

 

五:Overlapped I/O 完成例程模型

老陳接收到新的信件後,通常的程序是:打開信封—-掏出信紙 —-閱讀信件—-回覆信件 ……爲了進一步減輕用戶負擔,微軟又開發了一種新的技術:用戶只要告訴微軟對信件的操做步驟,微軟信箱將按照這些步驟去處理信件,再也不須要用戶親自拆信 /閱讀/回覆了!老陳終於過上了小資生活!

Overlapped I/O 完成例程要求用戶提供一個回調函數,發生新的網絡事件的時候系統將執行這個函數。

特色:由I/O來完成socket的拆包工做,實現異步。

 

六:IOCP 完成端口模型

微軟信箱彷佛很完美,老陳也很滿意。可是在一些大公司狀況卻徹底不一樣!這些大公司有數以萬計的信箱,每秒鐘都有數以百計的信件須要處理,以致於微軟信箱常常因超負荷運轉而崩潰!須要從新啓動!微軟不得不使出殺手鐗 ……
微軟給每一個大公司派了一名名叫」Completion Port」的超級機器人,讓這個機器人去處理那些信件!

特色:動用一個合理數量的線程來接受信息,而後把信息投送到應用程序。

「Windows NT小組注意到這些應用程序的性能沒有預料的那麼高。特別的,處理不少同時的客戶請求意味着不少線程併發地運行在系統中。由於全部這些線程都是可運行的 [沒有被掛起和等待發生什麼事], Microsoft意識到NT內核花費了太多的時間來轉換運行線程的上下文[Context],線程就沒有獲得不少CPU時間來作它們的工做。你們可能也都感受到並行模型的瓶頸在於它爲每個客戶請求都建立了一個新線程。建立線程比起建立進程開銷要小,但也遠不是沒有開銷的。咱們不妨設想一下:若是事先開好 N個線程,讓它們在那hold[堵塞 ],而後能夠將全部用戶的請求都投遞到一個消息隊列中去。而後那N 個線程逐一從消息隊列中去取出消息並加以處理。就能夠避免針對每個用戶請求都開線程。不只減小了線程的資源,也提升了線程的利用率。理論上很不錯,你想我等泛泛之輩都能想出來的問題, Microsoft又怎會沒有考慮到呢?」—– 摘自nonocast的《理解I/O Completion Port》

 

轉載:https://www.cnblogs.com/jikebiancheng/p/6225009.html

相關文章
相關標籤/搜索