![fdset參數(shù)一個用于檢查可讀性_第1頁](http://file4.renrendoc.com/view/72045a03598a6b9f3cf90b4f27f49ea7/72045a03598a6b9f3cf90b4f27f49ea71.gif)
![fdset參數(shù)一個用于檢查可讀性_第2頁](http://file4.renrendoc.com/view/72045a03598a6b9f3cf90b4f27f49ea7/72045a03598a6b9f3cf90b4f27f49ea72.gif)
![fdset參數(shù)一個用于檢查可讀性_第3頁](http://file4.renrendoc.com/view/72045a03598a6b9f3cf90b4f27f49ea7/72045a03598a6b9f3cf90b4f27f49ea73.gif)
![fdset參數(shù)一個用于檢查可讀性_第4頁](http://file4.renrendoc.com/view/72045a03598a6b9f3cf90b4f27f49ea7/72045a03598a6b9f3cf90b4f27f49ea74.gif)
![fdset參數(shù)一個用于檢查可讀性_第5頁](http://file4.renrendoc.com/view/72045a03598a6b9f3cf90b4f27f49ea7/72045a03598a6b9f3cf90b4f27f49ea75.gif)
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1ntselectsIntnfds,fcL&etFAR*readfds,fd_setFAR*wrltefds,fd_setFAR?exceptfdsRconststructtfmevalFAR*timeoutfd_set參數(shù):一個用于檢查可讀性(readfds),一個用于檢查可寫性(writefds),另一個用于例外數(shù)據(jù)(exceptfds)。從根本上說,fd_set數(shù)據(jù)類型代表著一系列特定套接字的集合。其中,readfds集合包括符合下述任何一個條件的套接字:■有數(shù)據(jù)可以讀入。.連接已經關閉、重設或中止?!黾偃缫颜{用了listen,而且一個連接正在建立,那么accept函數(shù)調用會成功。writefds集合包括符合下述任何一個條件的套接字:■有數(shù)據(jù)可以發(fā)出。.如果已完成了對一個非鎖定連接調用的處理,連接就會成功。最后,exceptfds集合包括符合下述任何一個條件的套接字:.假如已完成了對一個非鎖定連接調用的處理,連接嘗試就會失敗?!鲇袔猓∣ut-of-band,OOB)數(shù)據(jù)可供讀取。用select對套接字進行監(jiān)視之前,在自己的應用程序中,必須將套接字句柄分配給一個集合,設置好一個或全部讀、寫以及例外fd_set結構。將一個套接字分配給任何一個集合后,再來調用select,便可知道一個套接字上是否正在發(fā)生上述的I/O活動。Winsock提供了下列宏操作,可用來針對I/O活動,對fd_set進行處理與檢查:FD_CLR(s,*set):從set中刪除套接字s。FD_ISSET(s,*set):檢查s是否set集合的一名成員;如答案是肯定的是,則返回TRUE。FD_SET(s,*set):將套接字、加入集合set。FD_ZERO(*set):將set初始化成空集合。例如,假定我們想知道是否可從一個套接字中安全地讀取數(shù)據(jù),同時不會陷于無休止的“鎖定”狀態(tài),便可使用FD_SET宏,將自己的套接字分配給fd_read集合,再來調用select。要想檢測自己的套接字是否仍屬fd_read集合的一部分,可使用FD_ISSET宏。采用下述步驟,便可完成用select操作一個或多個套接字句柄的全過程:1) 使用FD_ZERO宏,初始化自己感興趣的每一個fd_set。2) 使用FD_SET宏,將套接字句柄分配給自己感興趣的每個fd_set。3) 調用select函數(shù),然后等待在指定的fd_set集合中,I/O活動設置好一個或多個套接字句柄。select完成后,會返回在所有fd_set集合中設置的套接字句柄總數(shù),并對每個集合進行相應的更新。4) 根據(jù)select的返回值,我們的應用程序便可判斷出哪些套接字存在著尚未完成(待決)的I/O操作一具體的方法是使用FD_ISSET宏,對每個fd_set集合進行檢查。5) 知道了每個集合中“待決”的I/O操作之后,對I/O進行處理,然后返回步驟1),繼續(xù)進行select處理。select返回后,它會修改每個fd_set結構,刪除那些不存在待決I/O操作的套接字句柄。intWSAAsyncSelectfSOCKETs,HMNDhWnd,unsignedint州sg.long1Event表用于WSAAsyncSelectk5數(shù)的網絡申件類型事件類主FD_READFD_WRITEFD_OOBFD_ACCEPTFD_CONNECIFD_CLOSEFD_QOSFD_GROUP_QOSFD_ROUTING_INIER.FACE_CEANGEFDADDRESSLISICHANGE應用程序想要接收有美是否可讀的通知,以便諉人數(shù)據(jù)叵用程序想要接喉有美是否可與的謂知,以便寫入數(shù)據(jù)應用程序想接收是否有萍外(OOBi數(shù)FD_READFD_WRITEFD_OOBFD_ACCEPTFD_CONNECIFD_CLOSEFD_QOSFD_GROUP_QOSFD_ROUTING_INIER.FACE_CEANGEFDADDRESSLISICHANGE應用程序想接收與—次連接或者多點]奇口操作完成的通知叵.用程序想接收與直接字美閉有關的通知應用程序想接收套套字*服務質(QoS)發(fā)生更改的通知應用程序想接收直接字組”阪務質V發(fā)生更改的通知(圮在沒什幺.用?處.為未來套接字組的使.用保留叵.用程序想接收在指定的方向上,與路由接口發(fā)生變化的通知應用程序想接喉骨對套接字的協(xié)諼家族.本拒氾址列表發(fā)生空化的通知IntWSAEventSelect<SOCKET£,WSAEVENThEventObject,long1NetworkEventsDWOROWSAWaitForHultipleEventstDWORDcEvents,constWSAEVENTFAR*1phEvents,BOOLfHiItAlbDWORDdwTimsouthBOOLfAlertable若WSAWaitForMultipleEvents收到一個事件對象的網絡事件通知,便會返回一個值,指出造成函數(shù)返回的事件對象。這樣一來,我們的應用程序便可引用事件數(shù)組中已傳信的事件,并檢索與那個事件對應的套接字,判斷到底是在哪個套接字上,發(fā)生了什么網絡事件類型。對事件數(shù)組中的事件進行引用時,應該用WSAWaitForMultipleEvents的返回值,減去預定義值WSA_WAIT_EVENT_0,得到具體的引用值(即索引位置)。如下例所示:Index=WSAWaTtForMultipleEvent$(PH+);HyEvent=EvenUrray[Index-WSA,WA[T_EVENT_0];知道了造成網絡事件的套接字后,接下來可調用WSAEnumNetworkEvents函數(shù),調查發(fā)生了什么類型的網絡事件。該函數(shù)定義如下:intWSAEnumNetworkEvents(socketS,NSAEVENThEventobject,LPWSANETMORKEVENTSIpNetuorkEventss參數(shù)對應于造成了網絡事件的套接字。hEventObject參數(shù)則是可選的;它指定了一個事件句柄,對應于打算重設的那個事件對象。由于我們的事件對象處在一個“已傳信”狀態(tài),所以可將它傳入,令其自動成為“未傳信”狀態(tài)。如果不想用hEventObject參數(shù)來重設事件,那么可使用WSAResetEvent函數(shù),該函數(shù)早先已經討論過了。最后一個參數(shù)是IpNetworkEvents,代表一個指針,指向WSANETWORKEVENTS結構,用于接收套接字上發(fā)生的網絡事件類型以及可能出現(xiàn)的任何錯誤代碼。下面是WSANETWORKEVENTS結構的定義:typedefStructJiSANETWORKEVENTS1ong1NetworkEvents:int1ErrorC?le[FDJ1A)(_EVENlTSl:}WSAHETWORKEVENTS,FAR*LPMSANETWORKEVENTS:創(chuàng)建套接字的時候,假如使用的是socket函數(shù),而非WSASocket函數(shù),那么會默認設置WSA_FLAG_OVERLAPPED標志。成功建好一個套接字,同時將其與一個本地接口綁定到一起后,便可開始進行重疊I/O操作,方法是調用下述的Winsock函數(shù),同時指定一個WSAOVERLAPPED結構(可選):■WSASend■WSASendTo■WSARecv.WSARecvFrom■WSAIoctl.AcceptEx.TrnasmitFile。WSAOVERLAPPED結構在一個重疊I/。請求的初始化,及其后續(xù)的完成之間,提供了一種溝通或通信機制。下面是這個結構的定義:typedefstructWSAOVERLAPPEDDWORD Internal\DWORD Internal High:DWORD Offset;DMQRD OffsetHigh:WSAEVENThEvent:〕WSAOVERLAPPED.FAR*=LFWSAOVERLAPPED;發(fā)現(xiàn)一次重疊請求完成之后,接著需要調用WSAGetOverlappedResult(取得重疊結構)函數(shù),判斷那個重疊調用到底是成功,還是失敗。該函數(shù)的定義如下:BOOLN5邸NQgrlappW幅w】t(SOCKETLPW5A0VEftLA.PPEDIpOverl?ppedpLPDWORD1pebTr^risfer.BOOLfhlait,LPDWORDIpdwFla^s2.完成例程“完成例程”是我們的應用程序用來管理完成的重疊I/O請求的另一種方法。完成例程其實就是一些函數(shù)。最開始的時候,我們將其傳遞給一個重疊I/O請求,在一個重疊I/O請求完成時由系統(tǒng)調用。它們的基本設計宗旨是通過調用者的線程,為一個已完成的I/O請求提供服務。除此以外,應用程序可通過完成例程,繼續(xù)進行重疊I/O處理。如果希望用完成例程為重疊I/O請求提供服務,在我們的應用程序中,必須為一個I/O定界Winsock函數(shù),指定一個完成例程,同時指定一個WSAOVERLAPPED結構。一個完成例程必須擁有下述函數(shù)原型:voidCALLBACKCompletionROUTlNEfDWORDdwError,□WORDcblr*ansferredaLPWSAOVERLAPPED^Overlapped,DWORDdwFlags在程序清單8-8中,我們向大家展示了如何構建一個簡單的服務器應用,令其采用前述的方法,通過完成例程,來實現(xiàn)對一個套接字請求的管理。該程序的編碼主要按下述步驟進行:1) 新建一個套接字,開始在指定端口上,監(jiān)聽一個進入的連接。2) 接受一個進入的連接請求。3) 為接受的套接字創(chuàng)建一個WSAOVERLAPPED結構。4) 在套接字上投遞一個異步WSARecv請求,方法是將WSAOVERLAPPED指定成為參數(shù),同時提供一個完成例程。5) 在將fAlertable參數(shù)設為TRUE的前提下,調用WSAWaitForMultipleEvents,并等待一個重疊I/O請求完成。重疊請求完成后,完成例程會自動執(zhí)行,而且WSAWaitForMultipleEvents會返回一個WSA_IO_COMPLETION。在完成例程內,可隨一個完成例程一道,投遞另一個重疊WSARecv請求。6) 檢查WSAWaitForMultipleEvents是否返回WSA_IO_COMPLETION。7) 重復步驟5)和6)。,我們的應用程序可用Win32的SleepEx函數(shù)將自己的線程置為一種可警告等待狀態(tài)。該函數(shù)也設計用于將我們的線程置入一種可警告等待狀態(tài),并可為已經完成的重疊I/O請求進行完成例程的處理(前提是將fAlertable參數(shù)設為TRUE)。用一個完成例程結束了重疊I/O請求之后,返回值是WSA_IO_COMPLETION,而不是事件數(shù)組中的一個事件對象索引。SleepEx函數(shù)的行為實際上和WSAWaitForMultipleEvents差不多,只是它不需要任何事件對象。對SleepEx函數(shù)的定義如下:WORDSleepE^CDWORDdwMH11seconds?BOOLbAlertabledwMilliseconds參數(shù)定義了SleepEx函數(shù)的等待時間,以毫秒為單位。假如將dwMilliseconds設為INFINITE,那么SleepEx會無休止地等待下去。bAlertable參數(shù)規(guī)定了一個完成例程的執(zhí)行方式。假如將bAlertable設為FALSE,而且進行了一次I/O完成回調,那么I/O完成函數(shù)不會執(zhí)行,而且函數(shù)不會返回,除非超過由dwMilliseconds規(guī)定的時間。若設為TRUE,那么完成例程會得到執(zhí)行,同時SleepEx函數(shù)返回WAIT_IO_COMPLETION。從本質上說,完成端口模型要求我們創(chuàng)建一個Win32完成端口對象,通過指定數(shù)量的線程,對重疊I/O請求進行管理,以便為已經完成的重疊I/O請求提供服務。要注意的是,所謂“完成端口”,實際是Win32、WindowsNT以及Windows2000采用的一種I/O構造機制,除套接字句柄之外,實際上還可接受其他東西。然而,本節(jié)只打算講述如何使用套接字句柄,來發(fā)揮完成端口模型的巨大威力。使用這種模型之前,首先要創(chuàng)建一個I/O完成端口對象,用它面向任意數(shù)量的套接字句柄,管理多個I/O請求。要做到這一點,需要調用CreateCompletionPort函數(shù)。該函數(shù)定義如下:intraweb(>人賤人愛*)HANDLECreaiteloC&liipletlonport(HANDLEFIleHandle,HANDLEExist1ngCompletionPort.DWORDCQmpletionkeyhDWORDNumberOfConcurtentTbreads在我們深入探討其中的各個參數(shù)之前,首先要注意該函數(shù)實際用于兩個明顯有別的目的:■用于創(chuàng)建一個完成端口對象。.將一個句柄同完成端口關聯(lián)到一起。對完成端口來說,將一個套結字邦定到完成端口后,WSARecv和WSASend會立即返回,提高了系統(tǒng)的效率。可以調用GetQueuedCompletionStatus來判斷WSARecv和WSASend是否完成。這樣主程序就可以完全等待接受新的連接,線程程序來等待WSARecv和WSASend是否完成了。我想這也是完成端口的真正含義吧。完成端口一個完成端口其實就是一個通知隊列,由操作系統(tǒng)把已經完成的重疊I/O請求的通知放入其中。當某項I/O操作一旦完成,某個可以對該操作結果進行處理的工作者線程就會收到一則通知。而套接字在被創(chuàng)建后,可以在任何時候與某個完成端口進行關聯(lián)。通常情況下,我們會在應用程序中創(chuàng)建一定數(shù)量的工作者線程來處理這些通知。線程數(shù)量取決于應用程序的特定需要。理想的情況是,線程數(shù)量等于處理器的數(shù)量,不過這也要求任何線程都不應該執(zhí)行諸如同步讀寫、等待事件通知等阻塞型的操作,以免線程阻塞。每個線程都將分到一定的CPU時間,在此期間該線程可以運行,然后另一個線程將分到一個時間片并開始執(zhí)行。如果某個線程執(zhí)行了阻塞型的操作,操作系統(tǒng)將剝奪其未使用的剩余時間片并讓其它線程開始執(zhí)行。也就是說,前一個線程沒有充分使用其時間片,當發(fā)生這樣的情況時,應用程序應該準備其它線程來充分利用這些時間片。其實可以把完成端口看成是系統(tǒng)維護的一個隊列,操作系統(tǒng)把重疊的I/O操作完成的事件通知放到該隊列中,由于是“操作完成”的事件通知所以命名為“完成端口”// 系統(tǒng)為你開一根內部線程去處理I/O請求////////////////////////////////////////////////你這個說法有誤,可以參考DDK中WDM驅動文檔系統(tǒng)不會新開內部線程來等待,它只是簡單交給設備去處理IO直到設備以它自己的方式(多數(shù)是中斷,即使有DMA)通知CPU,IO操作完成,系統(tǒng)(多數(shù)是響應中斷時)再通知Iocp(就是掛個消息了)因此,Iocp就是一個消息隊列// 我們基本上按下述步驟行事:1) 創(chuàng)建一個完成端口。第四個參數(shù)保持為0,指定在完成端口上,每個處理器一次只允許執(zhí)行一個工作者線程。2) 判斷系統(tǒng)內到底安裝了多少個處理器。3) 創(chuàng)建工作者線程,根據(jù)步驟2)得到的處理器信息,在完成端口上,為已完成的I/O請求提供服務。在這個簡單的例子中,我們?yōu)槊總€處理器都只創(chuàng)建一個工作者線程。這是由于事先已預計到,到時不會有任何線程進入“掛起”狀態(tài),造成由于線程數(shù)量的不足,而使處理器空閑的局面(沒有足夠的線程可供執(zhí)行)。調用CreateThread函數(shù)時,必須同時提供一個工作者例程,由線程在創(chuàng)建好執(zhí)行。本節(jié)稍后還會詳細討論線程的職責。4) 準備好一個監(jiān)聽套接字,在端口5150上監(jiān)聽進入的連接請求。5) 使用accept函數(shù),接受進入的連接請求。6) 創(chuàng)建一個數(shù)據(jù)結構,用于容納“單句柄數(shù)據(jù)”,同時在結構中存入接受的套接字句柄。7) 調用CreateIoCompletionPort,將自accept返回的新套接字句柄同完成端口關聯(lián)到一起。通過完成鍵(CompletionKey)參數(shù),將單句柄數(shù)據(jù)結構傳遞給CreateIoCompletionPort。8) 開始在已接受的連接上進行I/O操作。在此,我們希望通過重疊I/O機制,在新建的套接字上投遞一個或多個異步WSARecv或WSASend請求。這些I/O請求完成后,一個工作者線程會為I/O請求提供服務,同時繼續(xù)處理未來的I/O請求,稍后便會在步驟3)指定的工作者例程中,體驗到這一點。9) 重復步驟5)?8),直至服務器中止。2.完成端口和重疊I/O將套接字句柄與一個完成端口關聯(lián)在一起后,便可以套接字句柄為基礎,投遞發(fā)送與接收請求,開始對I/O請求的處理。接下來,可開始依賴完成端口,來接收有關I/O操作完成情況的通知。從本質上說,完成端口模型利用了Win32重疊I/O機制。在這種機制中,象WSASend和WSARecv這樣的WinsockAPI調用會立即返回。此時,需要由我們的應用程序負責在以后的某個時間,通過一個OVERLAPPED結構,來接收調用的結果。在完成端口模型中,要想做到這一點,需要使用GetQueuedCompletionStatus(獲取排隊完成狀態(tài))函數(shù),讓一個或多個工作者線程在完成端口上等待。該函數(shù)的定義如下:BOOLBetQu?uedComp1tus(HANDLECQnipl^tlanPort,LPDWORD1pNumb ByteiTransferred,LPDKORD1pComplet1onKeytLPOVERLAPPED*IpOverl,DWORDseconds。一旦所有套接字句柄都已關閉,便需在完成端口上,終止所有工作者線程的運行。要想做到這一點,需要使用PostQueuedCompletionStatus函數(shù),向每個工作者線程都發(fā)送一個特殊的完成數(shù)據(jù)包。該函數(shù)會指示每個線程都“立即結束并退出”。下面是PostQueuedCompletionStatus函數(shù)的定義:flOOLPcstQiieuedComplet'ionStatus(HANDLECompletionPort,DWORDdwNunberOfaytesTransferredFDWORDdtfCoirpIetionKey,LPDVERLAPPEDIpDverlappedI/O模型的問題現(xiàn)在,對于如何挑選最適合自己應用程序的I/O模型,大家心中可能還沒什么數(shù)。前面已經提到,每種模型都有自己的優(yōu)點和缺點。同開發(fā)一個簡單的鎖定模式應用相比(運行許多服務線程),其他每種I/O模型都需要更為復雜的編程工作。因此,針對客戶機和服務器應用的開發(fā),我們分別提供了下述建議。客戶機的開發(fā)若打算開發(fā)一個客戶機應用,令其同時管理一個或多個套接字,那么建議采用重疊I/O或WSAEventSelect模型,以便在一定程度上提升性能。然而,假如開發(fā)的是一個以Windows為基礎的應用程序,要進行窗口消息的管理,那么WSAAsyncSelect模型
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025委托招標代理合同
- 2025【合同范本】建筑工程施工合同示本
- 2025二手空調購銷合同范本
- 長城遺址修繕方案
- 促銷活動合同范例
- 2024年六年級品社下冊《去中學看看》說課稿2 蘇教版
- 配件報價實施方案
- 2024年五年級英語下冊 Unit 4 Did You Have a Nice Trip Lesson 19 Li Ming Goes Home說課稿 冀教版(三起)
- 貴州籠式球場護欄施工方案
- 砂石加工賬目處理方案
- 城市道路智慧路燈項目 投標方案(技術標)
- 水泥采購投標方案(技術標)
- 醫(yī)院招標采購管理辦法及實施細則(試行)
- 初中英語-Unit2 My dream job(writing)教學設計學情分析教材分析課后反思
- 廣州市勞動仲裁申請書
- 江西省上饒市高三一模理綜化學試題附參考答案
- 23-張方紅-IVF的治療流程及護理
- 頂部板式吊耳計算HGT-20574-2018
- 因數(shù)和倍數(shù)復習思維導圖
- LY/T 2986-2018流動沙地沙障設置技術規(guī)程
- 三級教育考試卷(電工)答案
評論
0/150
提交評論