呼叫的步驟如下:
抽象出乙個完成埠大概的處理流程:
1:建立乙個完成埠。
2:建立乙個執行緒a。
3:a執行緒迴圈呼叫getqueuedcompletionstatus()函式來得到io操作結果,這個函式是個阻塞函式。
4:主線程迴圈裡呼叫accept等待客戶端連線上來。
5:主線程裡accept返回新連線建立以後,把這個新的套接字控制代碼用createiocompletionport關聯到完成埠,然後發出乙個非同步的wsasend或者wsarecv呼叫,因為是非同步函式,wsasend/wsarecv會馬上返回,實際的傳送或者接收資料的操作由windows系統去做。
7:windows系統完成wsasend或者wsarecv的操作,把結果發到完成埠。
8:a執行緒裡的getqueuedcompletionstatus()馬上返回,並從完成埠取得剛完成的wsasend/wsarecv的結果。
9:在a執行緒裡對這些資料進行處理(如果處理過程很耗時,需要新開執行緒處理),然後接著發出wsasend/wsarecv,並繼續下一次迴圈阻塞在getqueuedcompletionstatus()這裡。
歸根到底概括完成埠模型一句話:
我們不停地發出非同步的wsasend/wsarecv io操作,具體的io處理過程由windows系統完成,windows系統完成實際的io處理後,把結果送到完成埠上(如果有多個io都完成了,那麼就在完成埠那裡排成乙個佇列)。我們在另外乙個執行緒裡從完成埠不斷地取出io操作結果,然後根據需要再發出wsasend/wsarecv io操作。
完成埠模型是怎樣實現的呢?我們先建立乙個完成埠(::createiocompletioport())。然後再建立乙個或多個工作執行緒,並指定他們到這個完成埠上去讀取資料。我們再將遠端連線的套接字控制代碼關聯到這個完成埠(還是用::createiocompletionport())。一切就ok了。
工作執行緒都幹些什麼呢?首先是呼叫::getqueuedcompletionstatus()函式在關聯到這個完成埠上的所有套接字上等待i/o的完成。再判斷完成了什麼型別的i/o。一般來說,有三種型別的i/o,op_accept,op_read和op_wirte。我們到資料緩衝區內讀取資料後,再投遞乙個或是多個同型別的i/o即可(::acceptex()、::wsarecv()、::wsasend())。對讀取到的資料,我們可以按照自己的需要來進行相應的處理。
這樣乙個iocp伺服器的框架就出來了。當然,要做乙個好的iocp伺服器,還有考慮很多問題,如記憶體資源管理、接受連線的方法、惡意的客戶連線、包的重排序等等。以上是個人對於iocp模型的一些理解與看法,還有待完善。另外各winsock api的用法參見msdn。
補充iocp模型的實現:
//建立乙個完成埠
handle hcompletport = createiocompletionport(invalid_handle_value, 0, 0, 0);
//接受遠端連線,並把這個連線的socket控制代碼繫結到剛才建立的iocp上
aconnect = accept(flistensock, addr, len);
createiocompletionport(aconnect, hcompletport, null, 0);
//建立cpu數*2 + 2個執行緒
system_info si;
getsysteminfo(&si);
for (int i = 1; si.dwnumberofprocessors*2+2; i++)
ok,就這麼簡單,我們要做的就是建立乙個iocp,把遠端連線的socket控制代碼繫結到剛才建立的iocp上,最後建立n個執行緒,並告訴這n個執行緒到這個iocp上去訪問資料就可以了。
再看一下trecvsendthread執行緒都幹些什麼:
讀寫執行緒只是簡單地檢查iocp是否完成了我們投遞的讀寫操作,如果完成了則再投遞乙個新的讀寫請求。
應該注意到,我們建立的所有trecvsendthread都在訪問同乙個iocp(因為我們只建立了乙個iocp),並且我們沒有使用臨界區!難道不會產生衝突嗎?不用考慮同步問題嗎?
這正是iocp的奧妙所在。iocp不是乙個普通的物件,不需要考慮執行緒安全問題。它會自動調配訪問它的執行緒:如果某個socket上有乙個執行緒a正在訪問,那麼執行緒b的訪問請求會被分配到另外乙個socket。這一切都是由系統自動調配的,我們無需過問。
例項:簡單實現,適合iocp入門
參考:《windows網路與通訊程式設計》
IOCP模型與網路程式設計
一。前言 在老師分配任務 嘗試利用iocp模型寫出服務端和客戶端的 給我時,腦子一片空白,並不知道什麼是iocp模型,會不會是像軟體設計模式裡面的工廠模式,裝飾模式之類的那些呢?嘿嘿,不過好像是乙個挺好玩的東西,挺好奇是什麼東西來的,又是乙個新知識啦 於是,開始去尋找一大堆的資料,為這個了解做準備,...
IOCP模型與EPOLL模型的比較
一 iocp和epoll之間的異同。異 1 iocp是windows系統下使用。epoll是linux系統下使用。2 iocp是io操作完畢之後,通過get函式獲得乙個完成的事件通知。epoll是當你希望進行乙個io操作時,向epoll查詢是否可讀或者可寫,若處於可讀或可寫狀態後,epoll會通過e...
IOCP模型和EPOLL模型的比較
iocp模型與epoll模型的比較 iocp i o completion port 常稱i o完成埠。iocp模型屬於一種通訊模型,適用於 能控制併發執行的 高負載伺服器的乙個技術。通俗一點說,就是用於高效處理很多很多的客戶端進行資料交換的乙個模型。或者可以說,就是能非同步i o操作的模型。三 網...