Windows下重疊IO模型_第1頁(yè)
Windows下重疊IO模型_第2頁(yè)
Windows下重疊IO模型_第3頁(yè)
Windows下重疊IO模型_第4頁(yè)
Windows下重疊IO模型_第5頁(yè)
已閱讀5頁(yè),還剩6頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Windows下重疊I/O模型(轉(zhuǎn)貼)重疊模型的優(yōu)點(diǎn)可以運(yùn)行在支持Winsock2的所有Windows平臺(tái),而不像完成端口只是支持NT 系統(tǒng)。比起阻塞、select、WSAAsyncSelect 以及 WSAEventSelect 等模型,重疊 I/O(Overlapped I/O)模型使應(yīng)用程序能達(dá)到更佳的系統(tǒng)性能。因?yàn)樗瓦@4種模型不同的是,使用重疊模型的應(yīng)用程序通 知緩沖區(qū)收發(fā)系統(tǒng)直接使用數(shù)據(jù),也就是說,如果應(yīng)用程序投遞了一個(gè)10KB大 小的緩沖區(qū)來(lái)接收數(shù)據(jù),且數(shù)據(jù)已經(jīng)到達(dá)套接字,則該數(shù)據(jù)將直接被拷貝到投遞 的緩沖區(qū)。而這4種模型種,數(shù)據(jù)到達(dá)并拷貝到單套接字接收緩沖區(qū)中,此時(shí)應(yīng)用程序 會(huì)

2、被告知可以讀入的容量。當(dāng)應(yīng)用程序調(diào)用接收函數(shù)之后,數(shù)據(jù)才從單套接字緩 沖區(qū)拷貝到應(yīng)用程序的緩沖區(qū),差別就體現(xiàn)出來(lái)了。從windows網(wǎng)絡(luò)編程中提供的試驗(yàn)結(jié)果中可以看到,在使用了 P4 1.7G Xero 處理器(CPU很強(qiáng)啊)以及768MB的回應(yīng)服務(wù)器中,最大可以處理4萬(wàn)多個(gè)SOCKET 連接,在處理1萬(wàn)2千個(gè)連接的時(shí)候CPU占用率才40%左右一一非常好的性 能,已經(jīng)直逼完成端口。重疊模型的基本原理說了這么多的好處,你一定也躍躍欲試了吧,不過我們還是要先提 一下重疊模型的基本原理。概括一點(diǎn)說,重疊模型是讓應(yīng)用程序使用重疊數(shù)據(jù)結(jié)構(gòu) (WSAOVERLAPPED),一次投遞一個(gè)或多個(gè)Winsock

3、 I/O請(qǐng)求。針對(duì)這些提交的請(qǐng) 求,在它們完成之后,應(yīng)用程序會(huì)收到通知,于是就可以通過自己另外的代碼來(lái) 處理這些數(shù)據(jù)了。需要注意的是,有兩個(gè)方法可以用來(lái)管理重疊IO請(qǐng)求的完成情況 (就是說接到重疊操作完成的通知):事件對(duì)象通知(event object notification)完成例程(completion routines),注意,這里并不是完成端口而本文只是講述如何來(lái)使用事件通知的的方法實(shí)現(xiàn)重疊IO模型,完成例程 的方法準(zhǔn)備放到下一篇講:)(內(nèi)容太多了,一篇寫不完啊),如沒有特殊說明,本文的重疊模型默認(rèn)就是指的基于事件通知的重疊模型。既然是基于事件通知,就要求將Windows事件對(duì)象與W

4、SAOVERLAPPED結(jié)構(gòu)關(guān) 聯(lián)在一起(WSAOVERLAPPED結(jié)構(gòu)中專門有對(duì)應(yīng)的參數(shù)),通俗一點(diǎn)講,就是。 對(duì)了,忘了說了,既然要使用重疊結(jié)構(gòu),我們常用的send, sendto, recv, recvfrom 也都要被 WSASend, WSASendto, WSARecv, WSARecvFrom 替換掉了,它 們的用法我后面會(huì)講到,這里只需要注意一點(diǎn),它們的參數(shù)中都有一個(gè) Overlapped參數(shù),我們可以假設(shè)是把我們的WSARecv這樣的操作操作“綁定” 到這個(gè)重疊結(jié)構(gòu)上,提交一個(gè)請(qǐng)求,其他的事情就交給重疊結(jié)構(gòu)去操心,而其中 重疊結(jié)構(gòu)又要與Windows的事件對(duì)象“綁定”在一起,

5、這樣我們調(diào)用完WSARecv 以后就可以“坐享其成”,等到重疊操作完成以后,自然會(huì)有與之對(duì)應(yīng)的事件來(lái) 通知我們操作完成,然后我們就可以來(lái)根據(jù)重疊操作的結(jié)果取得我們想要德數(shù)據(jù) 了。也許說了半天你還是不大明白,那就繼續(xù)往后面看吧。 -_-b,語(yǔ)言表達(dá)能力有限啊關(guān)于重疊模型的基礎(chǔ)知識(shí)下面來(lái)介紹并舉例說明一下編寫重疊模型的程序中將會(huì)使用到的幾 個(gè)關(guān)鍵函數(shù)。1. WSAOVERLAPPED 結(jié)構(gòu)這個(gè)結(jié)構(gòu)自然是重疊模型里的核心,它是這么定義的typedef struct _WSAOVERLAPPED (DWORD Internal;DWORD InternalHigh;DWORD Offset;DWORD

6、 OffsetHigh;WSAEVENT hEvent;/唯一需要關(guān)注的參數(shù),用來(lái)關(guān)聯(lián)WSAEvent 對(duì)象 WSAOVERLAPPED, *LPWSAOVERLAPPED;我們需要把WSARecv等操作投遞到一個(gè)重疊結(jié)構(gòu)上,而我們又需要一個(gè)與重疊結(jié) 構(gòu)“綁定”在一起的事件對(duì)象來(lái)通知我們操作的完成,看到了和hEvent參數(shù), 不用我說你們也該知道如何來(lái)來(lái)把事件對(duì)象綁定到重疊結(jié)構(gòu)上吧?大致如下: WSAEVENT event;/ 定義事件WSAOVERLAPPED AcceptOverlapped ; / 定義重疊結(jié)構(gòu)event = WSACreateEvent();/建立一個(gè)事件對(duì)象句柄Zer

7、oMemory(&AcceptOverlapped, sizeof(WSAOVERLAPPED); / 初始化重疊結(jié) 構(gòu)AcceptOverlapped.hEvent = event; / Done !2. WSARecv系列函數(shù)在重疊模型中,接收數(shù)據(jù)就要靠它了,它的參數(shù)也比recv要多,因?yàn)橐玫吨?疊結(jié)構(gòu)嘛,它是這樣定義的:int WSARecv(SOCKET s,/當(dāng)然是投遞這個(gè)操作的套接字一LPWSABUF lpBuffers,/ 接收緩沖區(qū),與Recv函數(shù)不同/需要一個(gè)由WSABUF結(jié)構(gòu)構(gòu)成的數(shù)組DWORD dwBufferCount,/ 數(shù)組中 WSABUF結(jié)構(gòu)的數(shù)量LPDWORD

8、 lpNumberOfBytesRecvd, / 如果接收操作立即完成,這里會(huì)返回函數(shù)調(diào)用接收到的字節(jié)數(shù)LPDWORD lpFlags,/ 說來(lái)話長(zhǎng)了,我們這里設(shè)置為0即可LPWSAOVERLAPPED lpOverlapped, / “綁定”的重疊結(jié) 構(gòu)LPWSAOVERLAPPED_COMPLETION_ROUTINElpCompletionRoutine/完成例程中將會(huì)用到的參數(shù),我們這里設(shè)置為NULL);返回值:WSA_IO_PENDING :最常見的返回值,這是說明我們的WSARecv操作成功了,但是I/O操作還沒有完成,所以我們就需要綁定一個(gè)事件來(lái)通知我們操作何時(shí)完成舉個(gè)例子:(變

9、量的定義順序和上面的說明的順序是對(duì)應(yīng)的,下同)SOCKET s;WSABUF DataBuf;/定義WSABUF結(jié)構(gòu)的緩沖區(qū)/初始化一下DataBuf#define DATA_BUFSIZE 5096char bufferDATA_BUFSIZE;ZeroMemory(buffer, DATA_BUFSIZE);DataBuf.len = DATA_BUFSIZE;DataBuf.buf = buffer;DWORD dwBufferCount = 1, dwRecvBytes = 0, Flags = 0;/建立需要的重疊結(jié)構(gòu)WSAOVERLAPPED AcceptOverlapped ;/

10、如果要處理多個(gè)操作,這里當(dāng)然需要一 個(gè)/ WSAOVERLAPPED 數(shù)組WSAEVENT event;/如果要多個(gè)事件,這里當(dāng)然也需要一個(gè)WSAEVENT數(shù)組/需要注意的是可能一個(gè)SOCKET同時(shí)會(huì)有一個(gè)以上的重疊請(qǐng)求,/也就會(huì)對(duì)應(yīng)一個(gè)以上的WSAEVENTEvent = WSACreateEvent();ZeroMemory(&AcceptOverlapped, sizeof(WSAOVERLAPPED);AcceptOverlapped.hEvent = event;/ 關(guān)鍵的一步,把事件句柄“綁定”到重疊結(jié)構(gòu)上/作了這么多工作,終于可以使用WSARecv來(lái)把我們的請(qǐng)求投遞到重疊結(jié)構(gòu)上

11、了,呼。WSARecv(s, &DataBuf, dwBufferCount, &dwRecvBytes,&Flags, &AcceptOverlapped, NULL);其他的函數(shù)我這里就不一一介紹了,因?yàn)槲覀儺吘惯€有MSDN這么個(gè)好幫手,而 且在講后面的完成例程和完成端口的時(shí)候我還會(huì)講到一些”_”WSAWaitForMultipleEvents 函數(shù)熟悉WSAEventSelect模型的朋友對(duì)這個(gè)函數(shù)肯定不會(huì)陌生,不對(duì),其實(shí)大家都 不應(yīng)該陌生,這個(gè)函數(shù)與線程中常用的WaitForMultipleObjects函數(shù)有些地方 還是比較像的,因?yàn)槎际窃诘却硞€(gè)事件的觸發(fā)嘛。因?yàn)槲覀冃枰录?lái)通知

12、我們重疊操作的完成,所以自然需要這個(gè)等待事件的函 數(shù)與之配套。DWORD WSAWaitForMultipleEvents(DWORD cEvents,/等候事件的總數(shù)量const WSAEVENT* lphEvents,/事件數(shù)組的指針BOOL fWaitAll,/ 設(shè)置為TRUE,則事件數(shù)組中所有事件被傳信的時(shí)候函數(shù)才會(huì)返回/ FALSE則任何一個(gè)事件被傳信函數(shù)都要返回 /我們這里肯定是要設(shè)置為FALSE的DWORD dwTimeout, /超時(shí)時(shí)間,如果超時(shí),函數(shù)會(huì)返回WSA_WAIT_TIMEOUT/如果設(shè)置為0,函數(shù)會(huì)立即返回/如果設(shè)置為WSA_INFINITE只有在某一個(gè)事件被傳信

13、后才會(huì)返回/在這里不建議設(shè)置為WSA_INFINITE,因?yàn)?。后面再講吧.-_-bBOOL fAlertable/ 在完成例程中會(huì)用到這個(gè)參數(shù),這里我們先設(shè)置為FALSE);返回值:WSA_WAIT_TIMEOUT :最常見的返回值,我們需要做的就是繼續(xù)WaitWSA_WAIT_FAILED :出現(xiàn)了錯(cuò)誤,請(qǐng)檢查 cEvents 和 lphEvents 兩個(gè)參 數(shù)是否有效如果事件數(shù)組中有某一個(gè)事件被傳信了,函數(shù)會(huì)返回這個(gè)事件的索引值,但是這 個(gè)索引值需要減去預(yù)定義值WSA_WAIT_EVENT_0才是這個(gè)事件在事件數(shù)組中的 位置。具體的例子就先不在這里舉了,后面還會(huì)講到注意:WSAWaitFo

14、rMultipleEvents 函數(shù)只能支持由 WSA_MAXIMUM_WAIT_EVENTS 對(duì)象定義的一個(gè)最大值,是64,就是說WSAWaitForMultipleEvents只能等待 64個(gè)事件,如果想同時(shí)等待多于64個(gè)事件,就要?jiǎng)?chuàng)建額外的工作者線程,就 不得不去管理一個(gè)線程池,這一點(diǎn)就不如下一篇要講到的完成例程模型了。WSAGetOverlappedResult 函數(shù)既然我們可以通過WSAWaitForMultipleEvents函數(shù)來(lái)得到重疊操作完成的通知,那么我們自然也需要一個(gè)函數(shù)來(lái)查詢一下重疊操作的結(jié)果,定義如下BOOL WSAGetOverlappedResult(SOCKET

15、 s,/ SOCKET,不用說了LPWSAOVERLAPPED lpOverlapped, / 這里是我們想要查詢結(jié)果的那個(gè)重疊結(jié)構(gòu)的指針LPDWORD lpcbTransfer,/ 本次重疊操作的實(shí)際接收(或發(fā)送)的字節(jié)數(shù)BOOL fWait,/設(shè)置為TRUE,除非重疊操作完成,否則函數(shù)不會(huì)返回/設(shè)置FALSE,而且操作仍處于掛起狀態(tài),那么函數(shù)就會(huì)返回FALSE / 錯(cuò)誤為 WSA_IO_INCOMPLETE /不過因?yàn)槲覀兪堑却录餍艁?lái)通知我們操作完成,所以我們這里設(shè)置成什么 都沒有作用LPDWORD IpdwFlags/ 指向DWORD的指針,負(fù)責(zé)接收結(jié)果標(biāo)志);這個(gè)函數(shù)沒什么難的,這

16、里我們也不需要去關(guān)注它的返回值,直接把參數(shù)填好調(diào) 用就可以了,這里就先不舉例了唯一需要注意一下的就是如果WSAGetOverlappedResult完成以后,第三個(gè)參數(shù) 返回是0,則說明通信對(duì)方已經(jīng)關(guān)閉連接,我們這邊的SOCKET, Event之類的 也就可以關(guān)閉了四。實(shí)現(xiàn)重疊模型的步驟作了這么多的準(zhǔn)備工作,費(fèi)了這么多的筆墨,我們終于可以開始著手編碼了。 其實(shí)慢慢的你就會(huì)明白,要想透析重疊結(jié)構(gòu)的內(nèi)部原理也許是要費(fèi)點(diǎn)功夫,但是 只是學(xué)會(huì)如何來(lái)使用它,卻是真的不難,唯一需要理清思路的地方就是和大量的 客戶端交互的情況下,我們得到事件通知以后,如何得知是哪一個(gè)重疊操作完成 了,繼而知道究竟該對(duì)哪一個(gè)

17、套接字進(jìn)行處理,應(yīng)該去哪個(gè)緩沖區(qū)中的取得數(shù)據(jù), everything will be OK。下面我們配合代碼,來(lái)一步步的講解如何親手完成一個(gè)重疊模型。【第一步】定義變量#define DATA_BUFSIZE4096/ 接收緩沖區(qū)大小SOCKETListenSocket,/ 監(jiān)聽套接字AcceptSocket;/與客戶端通信的套接字WSAOVERLAPPED AcceptOverlapped;/ 重疊結(jié)構(gòu)一個(gè)WSAEVENT EventArrayWSA_MAXIMUM_WAIT_EVENTS;/用來(lái)通知重疊操作完成的事件句柄數(shù)組WSABUFDataBufDATA_BUFSIZE;DWORDdw

18、EventTotal = 0,/ 程序中事件的總數(shù)dwRecvBytes = 0,/ 接收到的字符長(zhǎng)度Flags = 0;/ WSARecv的參數(shù)【第二步】創(chuàng)建一個(gè)套接字,開始在指定的端口上監(jiān)聽連接請(qǐng)求 和其他的SOCKET初始化全無(wú)二致,直接照搬即可,在此也不多費(fèi)唇舌了,需要 注意的是為了一目了然,我去掉了錯(cuò)誤處理,平常可不要這樣啊,盡管這里出錯(cuò) 的幾率比較小。WSADATA wsaData;WSAStartup(MAKEWORD(2,2),&wsaData);ListenSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 創(chuàng)建 TCP套接字S

19、OCKADDR_IN ServerAddr;分配端口及協(xié)議族并綁定ServerAddr.sin_family=AF_INET;ServerAddr.sin_addr.S_un.S_addr =htonl(INADDR_ANY);ServerAddr.sin_port=htons(11111);bind(ListenSocket,(LPSOCKADDR)&ServerAddr, sizeof(ServerAddr); / 綁 定套接字listen(ListenSocket, 5);開始監(jiān)聽【第三步】接受一個(gè)入站的連接請(qǐng)求AcceptSocket = accept (ListenSocket, N

20、ULL,NULL);當(dāng)然,這里是我偷懶,如果想要獲得連入客戶端的信息(記得論壇上也常有人問 到),accept的后兩個(gè)參數(shù)就不要用NULL,而是這樣SOCKADDR_IN ClientAddr;/ 定義一個(gè)客戶端得地址結(jié)構(gòu)作為參數(shù) int addr_length二sizeof(ClientAddr);AcceptSocket = accept(ListenSocket,(SOCKADDR*)&ClientAddr, &addr_length);/于是乎,我們就可以輕松得知連入客戶端的信息了LPCTSTR lpIP = inet_ntoa(ClientAddr.sin_addr);/ IPUIN

21、T nPort = ClientAddr.sin_port;/ Port【第四步】建立并初始化重疊結(jié)構(gòu)為連入的這個(gè)套接字新建立一個(gè)WSAOVERLAPPED重疊結(jié)構(gòu),并且象前面講到的那 樣,為這個(gè)重疊結(jié)構(gòu)從事件句柄數(shù)組里挑出一個(gè)空閑的對(duì)象句柄“綁定”上去。/創(chuàng)建一個(gè)事件/ dwEventTotal可以暫時(shí)先作為Event數(shù)組的索引EventArraydwEventTotal = WSACreateEvent();ZeroMemory(&AcceptOverlapped, sizeof(WSAOVERLAPPED);/ 置今AcceptOverlapped.hEvent = EventArray

22、dwEventTotal;/關(guān)聯(lián)事件char bufferDATA_BUFSIZE;ZeroMemory(buffer, DATA_BUFSIZE);DataBuf.len = DATA_BUFSIZE;DataBuf.buf = buffer;/初始化一個(gè)WSABUF結(jié)構(gòu)dwEventTotal +;總數(shù)加一【第五步】以WSAOVERLAPPED結(jié)構(gòu)為參數(shù),在套接字上投遞WSARecv請(qǐng)求各個(gè)變量都已經(jīng)初始化OK以后,我們就可以開始Socket操作了,然后讓 WSAOVERLAPPED結(jié)構(gòu)來(lái)替我們管理I/O請(qǐng)求,我們只用等待事件的觸發(fā)就OK 了。if(WSARecv(AcceptSocket

23、 ,&DataBuf,1,&dwRecvBytes,&Flags,& AcceptOverlapped, NULL) = SOCKET_ERROR)(/返回WSA_IO_PENDING是正常情況,表示IO操作正在進(jìn)行,不能立即完 成/如果不是WSA_IO_PENDING錯(cuò)誤,就大事不好了! !if(WSAGetLastError() != WSA_IO_PENDING) (/那就只能關(guān)閉大吉了closesocket(AcceptSocket);WSACloseEvent(EventArraydwEventTotal); 【第六步】 用WSAWaitForMultipleEvents函數(shù)等待重疊

24、操作返回的結(jié)果我們前面已經(jīng)給WSARecv關(guān)聯(lián)的重疊結(jié)構(gòu)賦了一個(gè)事件對(duì)象句柄,所以我們 這里要等待事件對(duì)象的觸發(fā)與之配合,而且需要根據(jù)WSAWaitForMultipleEvents函數(shù)的返回值來(lái)確定究竟事件數(shù)組中的哪一個(gè)事件 被觸發(fā)了,這個(gè)函數(shù)的用法及返回值請(qǐng)參考前面的基礎(chǔ)知識(shí)部分。DWORD dwIndex;/等候重疊I/O調(diào)用結(jié)束/因?yàn)槲覀儼咽录蚈verlapped綁定在一起,重疊操作完成后我們會(huì)接到事件 通知dwIndex = WSAWaitForMultipleEvents(dwEventTotal,EventArray ,FALSE ,WSA_INFINITE,FALSE);/注

25、意這里返回的Index并非是事件在數(shù)組里的Index,而是需要減去WSA_WAIT_EVENT_0dwIndex = dwIndex - WSA_WAIT_EVENT_0;【第七步】使用WSAResetEvent函數(shù)重設(shè)當(dāng)前這個(gè)用完的事件對(duì)象事件已經(jīng)被觸發(fā)了之后,它對(duì)于我們來(lái)說已經(jīng)沒有利用價(jià)值了,所以要將它重置 一下留待下一次使用,很簡(jiǎn)單,就一步,連返回值都不用考慮WSAResetEvent(EventArraydwIndex);【第八步】使用WSAGetOverlappedResult函數(shù)取得重疊調(diào)用的返回狀態(tài)這是我們最關(guān)心的事情,費(fèi)了那么大勁投遞的這個(gè)重疊操作究竟是個(gè)什么結(jié) 果呢?其實(shí)對(duì)于

26、本模型來(lái)說,唯一需要檢查一下的就是對(duì)方的Socket連接是否 已經(jīng)關(guān)閉了DWORD dwBytesTransferred;WSAGetOverlappedResult( AcceptSocket, AcceptOverlapped , &dwBytesTransferred, FALSE, &Flags);/先檢查通信對(duì)方是否已經(jīng)關(guān)閉連接/如果=0則表示連接已經(jīng),則關(guān)閉套接字if(dwBytesTransferred = 0)(closesocket(AcceptSocket);WSACloseEvent(EventArraydwIndex); / 關(guān)閉事件 return;【第九步】“享受”接

27、收到的數(shù)據(jù)如果程序執(zhí)行到了這里,那么就說明一切正常,WSABUF結(jié)構(gòu)里面就存有我們 WSARecv來(lái)的數(shù)據(jù)了,終于到了盡情享用成果的時(shí)候了!喝杯茶,休息一下吧DataBuf.buf就是一個(gè)char*字符串指針,聽?wèi){你的處理吧,我就不多說了【第十步】同第五步一樣,在套接字上繼續(xù)投遞WSARecv請(qǐng)求,重復(fù)步驟69這樣一路作下來(lái),我們終于可以從客戶端接收到數(shù)據(jù)了,但是回想起來(lái),呀,這樣豈不是只能收到一次數(shù)據(jù),然后程序不就Over 了?.-_-b 所 以我們接下來(lái)不得不重復(fù)一遍第四步和第五步的工作,再次在這個(gè)套接字上投遞 另一個(gè)WSARecv請(qǐng)求,并且使整個(gè)過程循環(huán)起來(lái),are u clear?大家

28、可以參考我的代碼,在這里就先不寫了,因?yàn)楦魑欢家欢ū任?smart,領(lǐng)悟了關(guān)鍵所在以后,稍作思考就可以靈活變通了??蛻舳饲闆r的注意事項(xiàng)完成了上面的循環(huán)以后,重疊模型就已經(jīng)基本上搭建好了 80%了,為 什么不是100%呢?因?yàn)樽屑?xì)一回想起來(lái),呀,這樣豈不是只能連接一個(gè)客戶端?是的,如果只處理一個(gè)客戶端,那重疊模型就半點(diǎn)優(yōu)勢(shì)也沒有了,我 們正是要使用重疊模型來(lái)處理多個(gè)客戶端。所以我們不得不再對(duì)結(jié)構(gòu)作一些改動(dòng)。首先,肯定是需要一個(gè)SOCKET數(shù)組,分別用來(lái)和每一個(gè)SOCKET通信其次,因?yàn)橹丿B模型中每一個(gè)SOCKET操作都是要“綁定”一個(gè)重疊結(jié)構(gòu)的,所 以需要為每一個(gè)SOCKET操作搭配一個(gè)WSAO

29、VERLAPPED結(jié)構(gòu),但是這樣說并不嚴(yán) 格,因?yàn)槿绻恳粋€(gè)SOCKET同時(shí)只有一個(gè)操作,比如WSARecv,那么一個(gè)SOCKET 就可以對(duì)應(yīng)一個(gè)WSAOVERLAPPED結(jié)構(gòu),但是如果一個(gè)SOCKET上會(huì)有WSARecv和 WSASend兩個(gè)操作,那么一個(gè)SOCKET肯定就要對(duì)應(yīng)兩個(gè)WSAOVERLAPPED結(jié)構(gòu), 所以有多少個(gè)SOCKET操作就會(huì)有多少個(gè)WSAOVERLAPPED結(jié)構(gòu)。然后,同樣是為每一個(gè)WSAOVERLAPPED結(jié)構(gòu)都要搭配一個(gè)WSAEVENT事件,所以 說有多少個(gè)SOCKET操作就應(yīng)該有多少個(gè)WSAOVERLAPPED結(jié)構(gòu),有多少個(gè) WSAOVERLAPPED結(jié)構(gòu)就應(yīng)該有多少個(gè)WSAEVENT事件,最好把SOCKET - WSAOVERLAPPED - WSAEVENT三者的關(guān)聯(lián)起來(lái),到了關(guān)鍵時(shí)刻才會(huì)臨危不亂:)不得不分作兩個(gè)線程:一個(gè)用來(lái)循環(huán)監(jiān)聽端口,接收請(qǐng)求的連接,然后給在這個(gè)套接字上配合一個(gè) WSAOVERLAPPED結(jié)構(gòu)投遞第一個(gè)WSARecv請(qǐng)求,然后進(jìn)入第二個(gè)線程中等待操作 完成。第二個(gè)線程用來(lái)不

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論