套接字I/O模型之WSAEventSelect

今天我又學習了一種新的套接字I/O模型------WSAEventSelect,他與WSAAsyncSelect一樣也是一種異步事件通知模型,不同的是WSAAsyncSelect是與窗口句柄關聯在一起的,必須要要窗口才行,而WSAEventSelect是與事件對象關聯的。這個模型的基本思路是爲感興趣的一組網絡事件創建一個事件對象,再調用WSAEventSelect函數將網絡事件和事件對象關聯起來。當網絡事件發生時,winsock使響應的事件對象受信,在事件對象上等待的函數就會立即返回。之後調用WSAEnumNetworkEvents函數便可獲得到底發生了什麼網絡事件(FD_READ/FD_ACCEPT/FD_CLOSE等等)。

 

用到的函數有:

WSACreateEvent  、WSAEventSelect、WSAWaitForMultipleEvents、WSAEnumNetworkEvents

等,這裏只詳細介紹下WSAWaitForMultipleEvents函數

 

關聯了事件對象後就可以用WSAWaitForMultipleEvents函數在一個或多個事件對象上等待了,當所等待的事件對象受信或者指定的時間過去了,此函數返回。

WSAWaitForMultipleEvents(

DWORD cEVents;                            //指定下面lpEvents所指的數組中事件對象句柄的個數

const WSAEVENT*  lpEvents;             //指向一個事件對象句柄的數組

BOOL fWaitAll;                     //指定是否等待所有的事件對象都變成受信狀態(爲TRUE:是;FALSE:否)

DWORD dwTimeout;            //指定要等待的時間,可以爲WSA_INFINITE

BOOL fAlertable;                  //設爲FALSE

);

 

函數最多可以支持WSA_MAXIMUM_WAIT_EVENTS個對象,他的大小是64.該函數會等待網絡事件的發生,如果過了指定了時間(dwTimeOut)則返回WSA_WAIT_TIMEOUT,如果在規定的時間內有事件發生,則返回該事件對象的索引(注意:在程序中要想得到發生的事件的真正索引需得用返回值減去WSA_WAIT_EVENT_0),調用失敗返回WSA_WAIT_FAILED.如果將參數fWaitAll設置成false如果有多個網絡事件發生該函數也只返回一個事件對象索引,並且該事件是在事件句柄數組中最前面的一個.解決方法是循環調用該函數處理後面的受信事件.
該函數的第一個參數是後面事件對象句柄數組的大小,第二個是個事件對象句柄數組,最後一個設置成false即可.
   一旦事件對象受信那麼找到與之對應的套接字,然後調用 int WSAEnumNetWorkEvent(SOCKET s, WSAEVENT hEventHandle, LPWSANETWORKEVENTS *LPWSANETWORKEVENTS)可以查看發生的網絡事件,第一個參數和相應的網絡事件標識做與運算就可.第二參數是返回的錯誤信息。

 

下面給分別給出用WSAEventSelect模型寫出的TCP/UDP服務器例子.

 

TCP例子:

 

TCP例子就是在監聽套接字上關聯一個事件對象以及FD_ACCEPT|FD_CLOSE網絡事件。

 

 

下面是UDP的例子:

 

 

UDP例子就是在一個普通套接字上關聯一個事件對象以及FD_READ網絡事件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章