• <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>

            8.2.4 重疊模型
            在Wi n s o c k中,相比我們迄今為止解釋過的其他所有I / O模型,重疊I / O(Overlapped I/O)
            模型使應用程序能達到更佳的系統性能。重疊模型的基本設計原理便是讓應用程序使用一個重疊的數據結構,一次投遞一個或多個Winsock I/O請求。針對那些提交的請求,在它們完成之后,應用程序可為它們提供服務。該模型適用于除Windows CE之外的各種Wi n d o w s平臺。
            模型的總體設計以Wi n 3 2重疊I / O機制為基礎。那個機制可通過R e a d F i l e和Wr i t e F i l e兩個函數,針對設備執行I / O操作。
            最開始的時候,Wi n s o c k重疊I / O模型只能應用于Windows NT操作系統上運行的Wi n s o c k1 . 1應用程序。作為應用程序,它可針對一個套接字句柄,調用R e a d F i l e以及Wr i t e F i l e,同時指定一個重疊式結構(稍后詳述),從而利用這個模型。自Winsock 2發布開始,重疊I / O便已集成到新的Wi n s o c k函數中,比如W S A S e n d和W S A R e c v。這樣一來,重疊I / O模型便能適用于安裝了Winsock 2的所有Wi n d o w s平臺。

            注意在Winsock 2發布之后,重疊I/O仍可在Windows NT和Windows 2000這兩個操作系統中,隨R e a d F i l e和Wr i t e F i l e兩個函數使用。但是,Windows 95和Windows 98均不具備這一功能。考慮到應用程序的跨平臺兼容問題,同時考慮到性能方面的因素,應盡量避免使用Wi n 3 2的R e a d F i l e和Wr i t e F i l e函數,分別換以W S A R e c v和W S A S e n d函數。本節只打算講述通過新的Winsock 2函數,來使用重疊I/O模型。
            要想在一個套接字上使用重疊I / O模型,首先必須使用W S A _ F L A G _ O V E R L A P P E D這個標志,創建一個套接字。如下所示:

            ? s = WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
            ? 創建套接字的時候,假如使用的是s o c k e t函數,而非W S A S o c k e t函數,那么會默認設置W S A _ F L A G _ O V E R L A P P E D標志。成功建好一個套接字,同時將其與一個本地接口綁定到一起后,便可開始進行重疊I / O 操作,方法是調用下述的Wi n s o c k 函數,同時指定一個
            W S A O V E R L A P P E D結構(可選):
            ■ W S A S e n d
            ■ W S A S e n d To
            ■ W S A R e c v
            ■ W S A R e c v F r o m
            ■ W S A I o c t l
            ■ A c c e p t E x
            ■ Tr n a s m i t F i l e
            大家現在或許已經知道,其中每個函數都與一個套接字上數據的發送、數據接收以及連接的接受有關。因此,這些活動可能會花極少的時間才能完成。這正是每個函數都可接受一個W S A O V E R L A P P E D結構作為參數的原因。若隨一個W S A O V E R L A P P E D結構一起調用這些函數,函數會立即完成并返回,無論套接字是否設為鎖定模式(本章開頭已詳細講過了)。它
            們依賴于W S A O V E R L A P P E D結構來返回一個I / O請求的返回。
            主要有兩個方法可用來管理一個重疊I / O請求的完成:我們的應用程序可等待“事件對象通知”,亦可通過“完成例程”,對已經完成的請求加以處理。上面列出的函數( A c c e p t E x除外)還有另一個常用的參數:
            l p C o m p l e t i o n R O U T I N E。該參數指定的是一個可選的指針,指向一個完成例程函數,在重疊請求完成后調用。接下去,我們將探討事件通知方法。在本章稍后,還會介紹如何使用可選的完成例程,代替事件,對完成的重疊請求加以處理。
            1. 事件通知
            重疊I / O的事件通知方法要求將Wi n 3 2事件對象與W S A O V E R L A P P E D結構關聯在一起。若使用一個W S A O V E R L A P P E D結構,發出像W S A S e n d和W S A R e c v這樣的I / O調用,它們會立即返回。
            通常,大家會發現這些I / O 調用會以失敗告終,返回S O C K E T _ E R R O R 。使用W S A G e t L a s t E r r o r函數,便可獲得與錯誤狀態有關的一個報告。這個錯誤狀態意味著I / O操作正在進行。稍后的某個時間,我們的應用程序需要等候與W S A O V E R L A P P E D結構對應的事件對象,了解一個重疊I / O請示何時完成。W S A O V E R L A P P E D結構在一個重疊I / O請求的初始化,及其后續的完成之間,提供了一種溝通或通信機制。下面是這個結構的定義:

            ?typedef struct WSAOVERLAPPED
            ?{
            ??DWORD?Internal;
            ??DWORD InternalHigh;
            ??DWORD Offset;
            ??DWORD OffsetHigh;
            ??WSAEVENT hEvent;
            ?}WSAOVERLAPPED,FAR *LPWSAOVERLPPED;
            ?
            其中,I n t e r n a l、I n t e r n a l H i g h、O ff s e t和O ff s e t H i g h字段均由系統在內部使用,不應由應用程序直接進行處理或使用。而另一方面, h E v e n t字段有點兒特殊,它允許應用程序將一個事件對象句柄同一個套接字關聯起來。大家可能會覺得奇怪,如何將一個事件對象句柄分配給該字段呢?正如我們早先在W S A E v e n t S e l e c t模型中講述的那樣,可用W S A C r e a t e E v e n t函數來創建一個事件對象句柄。一旦創建好一個事件句柄,簡單地將重疊結構的h E v e n t字段分配給事件句柄,再使用重疊結構,調用一個Wi n s o c k函數即可,比如W S A S e n d或W S A R e c v。
            一個重疊I / O請求最終完成后,我們的應用程序要負責取回重疊I / O操作的結果。一個重疊請求操作最終完成之后,在事件通知方法中, Wi n s o c k會更改與一個W S A O V E R L A P P E D結構對應的一個事件對象的事件傳信狀態,將其從“未傳信”變成“已傳信”。由于一個事件對象已分配給W S A O V E R L A P P E D結構,所以只需簡單地調用W S AWa i t F o r M u l t i p l e E v e n t s函數,從而判斷出一個重疊I / O調用在什么時候完成。該函數已在我們前面講述WSAEventSelect I/O模型時介紹過了。W S AWa i t F o r M u l t i p l e E v e n t s函數會等候一段規定的時間,等待一個或多個事件對象進入“已傳信”狀態。在此再次提醒大家注意: W S AWa i t F o r M u l t i p l e E v e n t s函數一次
            最多只能等待6 4個事件對象。發現一次重疊請求完成之后,接著需要調用W S A G e t O v e r l a p p e dR e s u l t(取得重疊結構)函數,判斷那個重疊調用到底是成功,還是失敗。該函數的定義如下:
            ?BOOL WSAGetOverlappedResult(
            ????????????????SOCKET s,
            ????????????????LPWSAOVERLAPPED?lpOverlapped,
            ????????????????LPWORD?lpcbTransfer,
            ????????????????BOOL??fWait,
            ????????????????LPWORD?lpdwFlags
            ???????????????);
            其中, s參數用于指定在重疊操作開始的時候,與之對應的那個套接字。l p O v e r l a p p e d參數是一個指針,對應于在重疊操作開始時,指定的那個W S A O V E R L A P P E D 結構。
            l p c b Tr a n s f e r參數也是一個指針,對應一個D W O R D(雙字)變量,負責接收一次重疊發送或接收操作實際傳輸的字節數。f Wa i t參數用于決定函數是否應該等待一次待決(未決)的重疊操作完成。若將f Wa i t設為T R U E,那么除非操作完成,否則函數不會返回;若設為FA L S E,而且操作仍然處于“待決”狀態,那么W S A G e t O v e r l a p p e d R e s u l t函數會返回FA L S E值,同時返回一個W S A _ I O _ I N C O M P L E T E(I / O操作未完成)錯誤。但就我們目前的情況來說,由于需要等候重疊操作的一個已傳信事件完成,所以該參數無論采用什么設置,都沒有任何效果。
            最后一個參數是l p d w F l a g s,它對應于一個指針,指向一個D W O R D(雙字),負責接收結果標志(假如原先的重疊調用是用W S A R e c v或W S A R e c v F r o m函數發出的)。
            如W S A G e t O v e r l a p p e d R e s u l t函數調用成功,返回值就是T R U E。這意味著我們的重疊I / O操作已成功完成,而且由l p c b Tr a n s f e r參數指向的值已進行了更新。若返回值是FA L S E,那么可能是由下述任何一種原因造成的:
            ■ 重疊I / O操作仍處在“待決”狀態。
            ■ 重疊操作已經完成,但含有錯誤。
            ■ 重疊操作的完成狀態不可判決,因為在提供給W S A G e t O v e r l a p p e d R e s u l t函數的一個或
            多個參數中,存在著錯誤。

            失敗后,由l p c b Tr a n s f e r參數指向的值不會進行更新,而且我們的應用程序應調用W S A G e t L a s t E r r o r函數,調查到底是何種原因造成了調用失敗。
            在程序清單8 - 7中,我們向大家闡述了如何編制一個簡單的服務器應用,令其在一個套接字上對重疊I / O操作進行管理,程序完全利用了前述的事件通知機制。對該程序采用的編程步驟總結如下:
            1) 創建一個套接字,開始在指定的端口上監聽連接請求。
            2) 接受一個進入的連接請求。
            3) 為接受的套接字新建一個W S A O V E R L A P P E D結構,并為該結構分配一個事件對象句柄。
            也將事件對象句柄分配給一個事件數組,以便稍后由W S AWa i t F o r M u l t i p l e E v e n t s函數使用。
            4) 在套接字上投遞一個異步W S A R e c v請求,指定參數為W S A O V E R L A P P E D結構。
            注意函數通常會以失敗告終,返回S O C K E T _ E R R O R錯誤狀態W S A _ I O _ P E N D I N G(I/O操作尚未完成)。
            5) 使用步驟3 )的事件數組,調用W S AWa i t F o r M u l t i p l e E v e n t s函數,并等待與重疊調用關聯在一起的事件進入“已傳信”狀態(換言之,等待那個事件的“觸發”)。
            6) WSAWa i t F o r M u l t i p l e E v e n t s函數完成后,針對事件數組,調用W S A R e s e t E v e n t(重設事件)函數,從而重設事件對象,并對完成的重疊請求進行處理。
            7) 使用W S A G e t O v e r l a p p e d R e s u l t函數,判斷重疊調用的返回狀態是什么。
            8) 在套接字上投遞另一個重疊W S A R e c v請求。
            9) 重復步驟5 ) ~ 8 )。
            這個例子極易擴展,提供對多個套接字的支持。方法是將代碼的重疊I / O處理部分移至一個獨立的線程內,讓主應用程序線程為附加的連接請求提供服務。
            程序清單8-7 采用事件機制的簡單重疊I / O處理示例

            Posted on 2006-09-15 22:05 艾凡赫 閱讀(1144) 評論(0)  編輯 收藏 引用 所屬分類: win32 sdk 編程網絡編程
            国产美女亚洲精品久久久综合| 狠色狠色狠狠色综合久久| 久久人人爽人人爽人人片AV东京热| 99久久亚洲综合精品成人| 久久国产成人| 久久久久亚洲AV无码专区体验| 99久久精品国产麻豆| 久久综合给合综合久久| 男女久久久国产一区二区三区| 欧美日韩中文字幕久久伊人| 久久亚洲国产成人影院| 久久亚洲国产欧洲精品一| 久久乐国产综合亚洲精品| 99久久婷婷国产一区二区| 久久久国产乱子伦精品作者 | 77777亚洲午夜久久多人| 久久亚洲国产精品一区二区| 久久丫忘忧草产品| 国产精品久久久久乳精品爆| 无遮挡粉嫩小泬久久久久久久 | 91亚洲国产成人久久精品| 久久婷婷五月综合色奶水99啪 | 99re久久精品国产首页2020| 色青青草原桃花久久综合| 精品乱码久久久久久夜夜嗨| 久久精品aⅴ无码中文字字幕不卡 久久精品aⅴ无码中文字字幕重口 | 国产成人久久精品区一区二区| 欧美久久亚洲精品| 久久成人国产精品一区二区| 国产成人精品免费久久久久| 亚洲精品无码久久久影院相关影片| 精品久久久久久99人妻| 国内精品伊人久久久久影院对白 | 久久久精品国产亚洲成人满18免费网站 | 国产精品久久久久乳精品爆| 久久精品9988| 欧美激情精品久久久久| 99久久国产综合精品网成人影院 | 国产精品日韩深夜福利久久 | 777午夜精品久久av蜜臀| 亚洲国产精品无码久久久蜜芽|