【轉】 Winsock工作模型

首先得弄清楚同步、異步、阻塞、非阻塞的概念。
同步和異步是針對通訊的工作模式,阻塞和非阻塞是指socket的I/O操作。
實際上對於socket,只存在阻塞和非阻塞,同步與異步是在程序實現上有所不同。
以阻塞的方式執行recv函數,在沒有收到數據前,此函數是不會返回的,所以這很容易執行函數的線程處於等待I/O上的數據狀態,然後被掛起。非阻塞就不一樣,執行recv時候不管有沒有數據都立即返回,有數據時返回數據,沒數據時返回錯誤。非阻塞可以帶來程序的高效,也帶來了寫程序中必須注意的地方,非阻塞情況下,發送與接收數據時候,要用戶自己管理自己的緩衝區,並且要記錄發送與接受的位置,因爲很可能發送與接受數據的任務不能一次完成,需要多次調用send和recv纔可以完成。
本來同步異步是用來表示通訊模式的,通信的同步,主要是指客戶端在發送請求後,必須得在服務端有迴應後才發送下一個請求。所以這個時候的所有請求將會在服務端得到同步。通信的異步,指客戶端在發送請求後,不必等待服務端的迴應就可以發送下一個請求,這樣對於所有的請求動作來說將會在服務端得到異步,這條請求的鏈路就象是一個請求隊列,所有的動作在這裏不會得到同步的。但是個人感覺,在說到socket的同步異步時候,同步跟阻塞概念差不多,都是有了結果才返回,異步則是告訴系統我要recv數據,然後馬上返回,等待數據來了後,系統跟程序說數據到了,然後程序再recv數據。引用在網上看到的比較好的描述“阻塞 block 是指,你撥通某人的電話,但是此人不在,於是你拿着電話等他回來,其間不能再用電話。同步大概和阻塞差不多。非阻塞 nonblock 是指,你撥通某人的電話,但是此人不在,於是你掛斷電話,待會兒再打。至於到時候他回來沒有,只有打了電話才知道。即所謂的“輪詢 / poll”。異步是指,你撥通某人的電話,但是此人不在,於是你叫接電話的人告訴那人(leave a message),回來後給你打電話(call back)。”

顯然,異步要高效一些。在Winsock中實現異步的方法有很多,Winsock工作模型有下面六種
    一:select模型
    二:WSAAsyncSelect模型
    三:WSAEventSelect模型
    四:Overlapped I/O 事件通知模型
    五:Overlapped I/O 完成例程模型
    六:IOCP模型
從一到六越來越高級,越來越高效,實現越來越複雜。曾在網上看到一些比喻用來很好的說明這些模型,在這裏引用一下。

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

老陳非常想看到女兒的信。以至於他每隔10分鐘就下樓檢查信箱,看是否有女兒的信~~~~~
在這種情況下,“下樓檢查信箱”然後回到樓上耽誤了老陳太多的時間,以至於老陳無法做其他工作。

二:WSAAsyncSelect模型

後來,老陳使用了微軟公司的新式信箱。這種信箱非常先進,一旦信箱裏有新的信件,蓋茨就會給老陳打電話:喂,大爺,你有新的信件了!從此,老陳再也不必頻繁上下樓檢查信箱了,牙也不疼了,你瞅準了,藍天......不是,微軟~~~~~~~~

三:WSAEventSelect模型

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

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

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

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

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

六:IOCP模型

微軟信箱似乎很完美,老陳也很滿意。但是在一些大公司情況卻完全不同!這些大公司有數以萬計的信箱,每秒鐘都有數以百計的信件需要處理,以至於微軟信箱經常因超負荷運轉而崩潰!需要重新啓動!微軟不得不使出殺手鐗......
微軟給每個大公司派了一名名叫“Completion Port”的超級機器人,讓這個機器人去處理那些信件!


其實,上面每種模型都有優點,要根據程序需求而適當選擇合適的模型,前面三種模型效率已經比較高,實現起來難道不大,很多一般的網絡程序都採用前三種模型,只有對網絡要求特別高的一些服務器纔會考慮用後面的那些模型。MFC中的CAsyncSocket類就是用的WSAAsyncSelect模型,電驢中也是用的這種,不過在尋找對應socket的時候進行了優化,查找更快,在GridCast中採用的是WSAEventSelect模型,等待。


BTW:上面所說均在Windows平臺下,只用WinSock纔有這麼多模型,在linux下,好像就只有第一種select模式,我對linux下的socket不是很瞭解,應該也有很多提高效率的地方。

 

轉自:http://www.cnblogs.com/flying_bat/archive/2008/01/18/1044737.html

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