青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

yehao's Blog

理解完成端口(IO completion port)

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/kevinlynx/archive/2008/01/27/2068739.aspx


  關于完成端口網上有很多文章,不過我個人覺得大多都講得不夠清楚。給的例子要不就是給一個復雜的封裝,要不就是給一個簡單的收發數據。注意,完成端口不僅僅用于網絡數據的收發,它可以用于windows 平臺的各種IO操作。不過我這里只關注在winsock編程中的應用。

    要寫出一篇真的讓人能夠明白的文章,不那么容易。這里我只暫時貼些我的理解。遲些時候如果有空的話,我倒有興趣寫個詳細的入門文章。

1.26.2008

Kevin Lynx

 
理解完成端口:
 
       就目前所了解的信息來說,完成端口通常都會與重疊IO有關聯。完成端口可被看作是一個隊列。各種操作都會被放到該隊列里,程序在遲些時候查詢此隊列獲取之前提交的IO操作結果。

       注意,無論是重疊IO還是完成端口,都不僅僅用于socket的操作,他們是用于各種IO的操作。


IOCP不是為每一個客戶端連接建立一個線程。

要區分IOCP和事件通知模型的區別,事件通知模型是先得到事件,然后根據事件類型去獲取或者發送數據;而IOCP則是先提交動作(發送或接收),后得到通知,當得到通知時,通常就意味著之前提交的動作已經完成了。

 
When you use IOCP, you spawn a pool of threads once - and they are used to handle the network I/O in your application. Technically, in Windows 2000, you don't even have to spawn the pool yourself - you can let Windows take care of the spawning and management of the threads in the pool。

IOCP其實也屬于一種同步對象,就像Windows里的Event對象一樣。IOCP用于同步IO操作。在異步IO操作中,提交了一個異步操作后,某些時候就需要得知操作的結果,也就是同步一下。

 
http://www.codeproject.com/KB/IP/iocp_server_client.aspx
A server application is fairly meaningless if it cannot service multiple clients at the same time, usually asynchronous I/O calls and multithreading is used for this purpose. By definition, an asynchronous I/O call returns immediately, leaving the I/O call pending. At some point of time, the result of the I/O asynchronous call must be synchronized with the main thread. This can be done in different ways. The synchronization can be performed by:
•Using events - A signal is set as soon as the asynchronous call is finished. The disadvantage of this approach is that the thread has to check or wait for the event to be set. •Using the GetOverlappedResult function - This approach has the same disadvantage as the approach above. •Using Asynchronous Procedure Calls (or APC) - There are several disadvantages associated with this approach. First, the APC is always called in the context of the calling thread, and second, in order to be able to execute the APCs, the calling thread has to be suspended in the so called alterable wait state. •Using IOCP - The disadvantage of this approach is that there are many practical thorny programming problems that must be solved. Coding IOCP can be a bit of a hassle. 
這里我要特別強調一下異步IO和非阻塞IO的區別,異步IO就是把IO提交給系統,讓系統替你做,做完了再用某種方式通知你;非阻塞IO就是你要通過某種方式不定時地向系統詢問你是否可以開始做某個IO,當可以開始后,還是要自己來完成IO。
 
       不可以通過接受數據是否為0來判斷客戶端是否斷開,只有當調用closesocket時才可以通過這個方法判斷,如果是意外退出(斷電,網絡故障),則判斷不出。這個時候可以采用定時發送數據(心跳信息)來確認。

 
       創建IOCP程序,一般的步驟:

1.       創建一個單句柄數據結構體,該結構體里一般都包含一個套接字數據。因為IOCP實際上會有固定的幾個線程(工作線程),這些線程在IOCP結果隊列里查詢IO操作結果。這些結果不止是在一個套接字上進行的操作(讀或寫),而是包括了所有與該IOCP對象關聯起來的套接字上的操作結果。因此,為了區分某次操作結果屬于哪個套接字,就需要這個單句柄數據結構里包含這個套接字句柄。

2.       創建一個以OVERLAPPED為首個元素的數據結構體。該結構體實際上對應著一個IO操作(例如WSASend)。對于 WSASend, WSARecv以及查詢操作結果函數都需要一個OVERLAPPED參數(一般是指針),通常情況下我們需要更多的數據,因此定義的這個結構體里通常包含了更多的數據(例如WSABUF,它可以用來容納WSARecv接受到的數據)。之所以要把OVERLAPPED 作為這個結構體的第一個元素,是為了在使用查詢函數GetQueuedCompletionStatus后,可以通過該函數返回的OVERLAPPED類型的指針得到我們這里定義的結構體對象地址,從而獲取更多的數據。

3.       每一次接受到新的連接時(accept),都將這個新的套接字與完成端口相關聯。并且創建一個單句柄對象(也就是完成鍵)。每一個套接字都有一個關聯的單句柄對象。而每一個IO操作都有一個關聯的OVERLAPPED相關的數據結構(上一步定義的結構體)。

4.       可以在任何時候提交異步IO請求,例如WSASend, WSARecv。這里需要為OVERLAPPED相關的結構體指定操作類型。一個典型的結構體為(即第二步定義的結構體):

              struct IOContext
{
              /// 很多函數需要此參數
              OVERLAPPED ol;
              /// 存放接受數據
              char buf[MAX_BUF];
              ///
              WSABUF wsabuf;
              /// 操作類型,提交IO操作時指定該值,在查詢操作結果時,可以重新獲取到該值
              int op_type;
};
在創建該結構體的變量時,為op_type指定一個值。然后將此結構體的地址給WSASend之類的函數。在工作者線程中執行查詢時,實際上得到了該結構體的地址(結構體變量),那么,就可以獲取op_type的值。
注意:查詢結構只能獲取IO操作的字節數(以及IO操作結果數據),不能知道IO操作的類型。所以IO操作的類型實際上是在這里用戶自己指定的。
當執行WSASend時,設置op_type為SEND(自己定義的常量),執行WSARecv時,指定READ。然后在查詢結果時,可以根據op_type知道這個操作結果是什么類型。如果是SEND,那么就表示之前提交的WSASend操作。
IOCP是一個異步操作機制,之所以是異步,就是因為可以隨時提交IO操作。提交之后具體的操作由系統為你完成。完成后就需要某種機制來得知操作結果。IOCP設置的這個結果隊列就是一種機制。
 
      
 
5.       可以通過PostQueuedCompletionStatus手動地往結果隊列里放置一個操作結果。通常這個函數都用于讓工作者線程退出。例如:

                   PostQueuedCompletionStatus( cp_handle, 0, NULL, NULL );
然后在工作者線程里:

         ret = GetQueuedCompletionStatus( cp_handle, &transfer_bytes, (PULONG_PTR) &hc,
              (LPOVERLAPPED*)&ic, INFINITE );
         if( ic == NULL )
         {
              printf( "ic == NULL\n" );
              /*
                   使用PostQueuedCompletionStatus傳遞過來的數據,
                   這里約定ic==NULL時退出
              */
              break;
         }
        
6.     如果不提交任何IO操作,那么結果隊列里很有可能一直都是空的。那么GetQueued這個查詢函數就會一直得不到數據。
 
7.     縱觀IOCP程序,一個比較復雜的地方在于資源的釋放。在接收到一個新的連接時,會為這個連接創建單句柄數據,執行IO操作的話,還要創建OVERLAPPED相關結構體變量。這些變量的地址都會在工作者線程中通過GetQueued..函數獲取,并在工作者線程中使用。一個比較直接的做法是在工作者線程中釋放這些資源。
 
 
 
推薦些文章:

幾種socket模型的代碼:http://blog.csdn.net/mlite/archive/2006/04/30/699340.aspx
                  又一個簡單的IOCP代碼:http://www.go321.cn/html/app/cpp/20070526/30207.html
                  另一個例子,那幅圖有點意義:http://www.3800hk.com/Article/cxsj/vc/wllbcvc/2005-08-25/Article_54111.html
                  codeproject上的文章:http://www.codeproject.com/KB/IP/iocp_server_client.aspx
                  codeproject上的另一篇:http://www.codeproject.com/KB/IP/jbsocketserver1.aspx
                  MSDN上的,前部分由點意義:http://msdn.microsoft.com/msdnmag/issues/1000/winsock/
                
                 其實完成端口的例子在細節上有很多方法,例如accept, AcceptEx之類,對于accept的處理尤其多。這些無疑又給初學者帶來了迷惑。我覺得只要把握住幾個要點就行了:異步操作,結果隊列,數據的傳送(提交操作時傳進去,查詢時取出來),工作者線程

posted on 2011-04-24 18:59 厚積薄發 閱讀(3089) 評論(0)  編輯 收藏 引用 所屬分類: 網絡編程

導航

<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

統計

常用鏈接

留言簿

隨筆分類

文章分類

文章檔案

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            91久久精品国产| 男女视频一区二区| 日韩一级大片| 久久精品免费电影| 性欧美精品高清| 欧美精品亚洲| 你懂的视频一区二区| 国产日韩欧美中文| 一片黄亚洲嫩模| 一本一本a久久| 欧美 日韩 国产 一区| 久久婷婷国产麻豆91天堂| 国产精品另类一区| 日韩视频免费在线| 亚洲精品视频在线看| 久久综合伊人77777蜜臀| 久久精品国产一区二区电影| 国产精品久久波多野结衣| 亚洲精品女av网站| 在线观看亚洲视频| 久久免费少妇高潮久久精品99| 午夜在线a亚洲v天堂网2018| 欧美午夜视频网站| 一区二区精品在线| 亚洲直播在线一区| 国产精品久久999| 亚洲香蕉成视频在线观看 | 合欧美一区二区三区| 午夜一级在线看亚洲| 欧美夜福利tv在线| 国产亚洲精品久久久久动| 性做久久久久久久免费看| 久久aⅴ国产欧美74aaa| 国产亚洲福利| 久久精品国产久精国产爱| 久久女同互慰一区二区三区| 一区在线播放| 欧美成年人视频网站| 亚洲精品综合| 亚洲综合色婷婷| 国产欧美日韩在线视频| 久久精品视频播放| 欧美激情第六页| 一区二区三区av| 国产精品亚发布| 久久精品国产综合| 最新日韩av| 亚洲欧美日本国产有色| 国产一区二三区| 老司机久久99久久精品播放免费 | 欧美成人a视频| 亚洲精品色图| 国产精品高潮久久| 久久国产精品99久久久久久老狼| 欧美大片一区二区| 亚洲永久精品大片| 国产一区二区三区久久久| 美女网站久久| 亚洲视频在线观看视频| 老司机成人在线视频| 99re热这里只有精品免费视频| 欧美性大战久久久久久久| 欧美怡红院视频| 亚洲第一福利社区| 午夜激情亚洲| 亚洲人成人77777线观看| 国产精品黄色在线观看| 久久久亚洲欧洲日产国码αv | 99精品国产福利在线观看免费| 欧美一区在线直播| 亚洲精品欧美| 国产资源精品在线观看| 欧美日韩成人一区二区| 久久久999精品| 一区二区三区日韩精品| 久久夜色精品| 亚洲欧美在线一区| 亚洲精品久久在线| 黄色日韩在线| 国产精品免费看片| 欧美大片在线观看一区二区| 欧美一二三视频| 夜夜爽99久久国产综合精品女不卡| 久久免费视频在线| 午夜在线电影亚洲一区| 在线午夜精品自拍| 最新成人在线| 在线精品国产欧美| 国产一区二区久久精品| 国产精品女人毛片| 欧美日韩视频在线第一区| 久色成人在线| 久久久久久综合| 亚洲免费影视第一页| 99视频精品全国免费| 亚洲国产美女| 亚洲高清在线观看一区| 老鸭窝亚洲一区二区三区| 久久成人免费网| 午夜激情亚洲| 亚洲欧美久久久| 一区二区三区福利| 日韩午夜在线| 亚洲精品在线看| 亚洲欧洲综合另类在线| 亚洲品质自拍| 亚洲精品免费在线播放| 亚洲精品午夜精品| 亚洲美女av在线播放| 亚洲乱码日产精品bd| 亚洲精品欧美在线| 日韩亚洲一区二区| 亚洲天堂av在线免费观看| 一区二区三区欧美| 亚洲一区二区三区免费观看| 亚洲尤物在线视频观看| 亚洲欧美日韩视频二区| 性伦欧美刺激片在线观看| 欧美一区二区三区成人| 久久国产精品99精品国产| 久久成年人视频| 老司机精品导航| 欧美激情中文不卡| 亚洲日本久久| 一本久久精品一区二区| 亚洲男女自偷自拍| 久久精品国产第一区二区三区最新章节| 午夜精品一区二区三区四区| 久久精品国产亚洲精品| 麻豆精品精品国产自在97香蕉| 欧美韩国一区| 国产精品久久久久久久久久直播| 国产伦精品一区二区| 欲香欲色天天天综合和网| 亚洲人成在线观看网站高清| 亚洲图片你懂的| 久久久久久久一区二区| 亚洲电影在线| 亚洲一品av免费观看| 久久久久免费| 欧美日韩一区三区| 黄色av日韩| 一本久久a久久免费精品不卡| 欧美一区二区三区免费大片| 两个人的视频www国产精品| 亚洲免费观看高清完整版在线观看熊 | 亚洲午夜久久久久久久久电影网| 欧美亚洲一区二区三区| 美女任你摸久久| 国产精品久久午夜夜伦鲁鲁| 在线观看成人av电影| 99国内精品| 欧美在线精品一区| 亚洲激情自拍| 久久久久91| 国产精品白丝黑袜喷水久久久 | 国产精品香蕉在线观看| 亚洲国产日韩在线一区模特| 亚洲欧美日韩爽爽影院| 欧美成人乱码一区二区三区| 在线中文字幕日韩| 蜜臀99久久精品久久久久久软件| 国产精品二区在线| 亚洲精品乱码视频| 久久人人97超碰国产公开结果| 99国产麻豆精品| 久久综合久久久久88| 国产日产高清欧美一区二区三区| 夜夜爽夜夜爽精品视频| 老司机凹凸av亚洲导航| 亚洲一区bb| 欧美日韩国产小视频| 亚洲高清二区| 久久亚洲精品一区| 午夜精品99久久免费| 国产精品多人| 一区二区日韩伦理片| 模特精品裸拍一区| 久久精品人人做人人爽| 国产精品任我爽爆在线播放| 宅男噜噜噜66一区二区| 亚洲观看高清完整版在线观看| 久久精品亚洲精品国产欧美kt∨| 国产精品青草久久久久福利99| 中文久久精品| 一本久久a久久免费精品不卡| 欧美片在线播放| 亚洲毛片一区| 亚洲国产一区在线观看| 欧美福利视频| 亚洲精品网站在线播放gif| 欧美激情一区二区三区高清视频| 久久久夜夜夜| 亚洲第一区在线观看| 另类国产ts人妖高潮视频| 久久久女女女女999久久| 一区二区三区在线观看国产| 麻豆精品网站| 免费试看一区| 亚洲作爱视频|