WSAAsyncSelect模型詳解

2021-06-19 16:58:10 字數 3385 閱讀 6700

ps:這是本人第一次在csnd上寫部落格,由於水平有限,還請各位大神批評指正。

一、wsaasyncselect模型介紹

wsaasyncselect模型是windows sockets的乙個非同步i/o模型。應用程式可以用它在乙個套接字上接收以windows訊息為基礎的網路事件。應用程式建立套接字後,呼叫wsaasyncselect()函式註冊感興趣的網路事件,當事件發生時,windows視窗接收到訊息,然後程式就可以對收到的網路事件進行處理。

select模型是阻塞的,而wsaasyncselect模型是非阻塞的。應用程式在呼叫recv()函式接收資料之前,呼叫wsaasyncselect()函式註冊網路事件。wsaasyncselect()函式立即返回,執行緒繼續執行。當系統中資料準備好時,向應用程式傳送訊息。程式接收到訊息後呼叫recv()函式接收資料。

二、wsaasyncselect()函式

函式原型:int  wsaasyncselect ( socket  s, hwnd  hwnd, u_int  wmsg, long  levent)

引數說明:s: 需要事件通知的套接字

hwnd:當網路事件發生時接收訊息的視窗控制代碼

wmsg:當網路事件發生時視窗收到的訊息

levent:應用程式感興趣的網路事件集合

使用說明:當應用程式中呼叫該函式後,自動將套接字設定為非阻塞模式。通常,應用程式宣告的訊息要比windows的wm_user值大,以避免該訊息與windows預定義的訊息發生混淆。

網路事件的種類和含義如下

網路事件型別 種類

含義fd_read

欲接收可讀的通知

fd_write

欲接收可寫的通知

fd_accept

欲接收等待接受連線的通知

fd_connect

欲接收一次連線或者多點jion操作完成的通知

fd_oob

欲接收有帶外(oob)資料到達的通知

fd_close

欲接收套接字關閉的通知

fd_qos

欲接收套接字服務質量發生變化的通知

fd_group_qos

欲接收套接字組服務質量發生變化的通知

fd_routing_inte***ce_change

欲在指定方向上,與路由介面發生變化的通知

fd_address_list_change

欲接收針對套接字的協議族,本地位址列表發生變化的通知

可根據需要同時註冊多個網路事件,這時要把網路事件型別執行按位或(or)運算,然後將它們分配給levent引數。例如:應用程式希望在套接字上接收連線完成、資料可讀和套接字關閉的網路事件,則呼叫如下函式:

wsaasyncselect ( s,  hwnd,   wm_socket,  fd_connect | fd_read | fd_close);

當該套接字連線完成、有資料可讀或者套接字關閉的網路事件發生時,就會有wm_socket

訊息傳送給視窗控制代碼為hwnd的視窗。

三、呼叫wsaasyncselect()函式需要注意的問題

1.接收不到網路事件

第一種情況是由於在同乙個套接字同乙個自定義訊息上,多次呼叫wsaasyncselect()函式註冊不同的網路事件,最後一次函式呼叫取消了前面註冊的網路事件。

如:wsaasyncselect ( s,  hwnd,   wm_socket,  fd_read);

wsaasyncselect ( s,  hwnd,   wm_socket,  fd_write);

此時應用程式只能接收到fd_write網路事件。

如果要取消所有的網路事件通知,告知windows sockets實現不再為該套接字傳送任何網路事件相關的訊息,要以引數levent值為0呼叫函式,即wsaasyncselect ( s,  hwnd,   0,  0)。儘管應用程式呼叫上述函式取消了網路事件通知,但是在應用程式訊息佇列中,可能還有網路訊息在排隊。所以呼叫上述函式取消網路事件訊息後,應用程式還應該繼續準備接收網路事件。

第二種情況是在同乙個套接字上,多次呼叫wsaasyncselect()函式,為不同網路事件定義了不同的訊息,最後一次該函式呼叫將取消前面註冊的網路事件。

如:wsaasyncselect ( s,  hwnd,   wmsg1,  fd_read);

wsaasyncselect ( s,  hwnd,   wmsg2,  fd_write);

第二次函式呼叫將會取消第一次函式呼叫的作用,只有fd_write網路事件通過wmsg2通知到視窗。

2. accept()函式

因為呼叫accept()函式接受的套接字和監聽套接字具有同樣的屬性,所以任何為監聽套接字設定的網路事件對接受的套接字同樣起作用。如果乙個監聽套接字請求fd_read和fd_write網路事件,則在該監聽套接字上接受的任何套接字也會請求fd_read和fd_write網路事件,以及傳送同樣的訊息。

3.關於fd_read網路事件

不要為乙個fd_read網路事件多次呼叫recv()函式。如果為乙個fd_read網路事件呼叫了多個recv()函式,會使得該應用程式接收到多個fd_read網路事件。

如果在一次接收fd_read網路事件時需要呼叫多次recv()函式,應用程式應該在呼叫recv()函式之前關閉fd_read訊息。

4.如何判斷套接字已經關閉

要使用fd_close網路事件來判斷套接字是否已經關閉。

接收fd_close網路事件時,錯誤**指示出套接字是從容關閉還是硬關閉。如果錯誤**為0,則為從容關閉;若錯誤**為wsaeconnreset,則套接字是硬關閉。

5.傳送資料失敗

乙個應用程式當接收到第乙個fd_write網路事件後,便認為在該套接字上可以傳送資料。當呼叫輸出函式傳送資料時,會收到wsaewouldblocke錯誤。經過這樣的失敗後,要在下一次接收到fd_write網路事件後,再次傳送資料,才能夠將資料成功傳送。

四、wsaasyncselect模型的優缺點

1.優點

該模型的使用方便了在基於訊息的windows環境下開發套接字應用程式。開發人員可以像處理其他訊息一樣對網路事件訊息進行處理。該模型為確保接收所有資料提供了很好的機制,通過註冊fd_close網路事件,從容關閉伺服器與客戶端的連線,保證了資料的全部接收。

2.缺點

該模型的侷限在於它基於windows的訊息機制,必須在應用程式中建立視窗。當然,在開發中可以根據具體情況確定是否顯示該視窗。

由於呼叫wsaasyncselect()函式後,自動將套接字設定為非阻塞狀態。當應用程式為接收到網路事件呼叫相應的函式時,未必能夠成功返回。這無疑增加了開發人員使用該模型的難度。對於這一點,可以從mfc csocket類的accept()、receive()、和send()函式的實現中得到驗證。

訊息機制 WSAAsyncSelect

訊息機制 wsaasyncselect wsaasyncselect基於windows訊息機制非同步i o模型,為特定網路事件指定系統通知資訊.函式定義 int wsaasyncselect socket s,hwnd hwnd,unsigned int wmsg,long levent 1 引數4...

WSAasyncSelect 非同步選擇訊息模型

wsaasyncselect 非同步選擇訊息模型適用於簡單對效率要求不太高的windows視窗程式。該模型windows為使用者封裝好了執行緒呼叫,以訊息的方式通知accep recv等事件是否已經發生,不用一直阻塞等待。下面是這種模型的簡單 實現 主要針對伺服器accept 和recv做非同步呼叫...

WSAASyncSelect模式的乙個小經驗

wsaasyncselect 模式fd close 訊息通常會在最後乙個 fd read 訊息之前出現,也就是說,當資料接收完之後,系統常會先傳送 fd close 訊息,然後才傳送 fd read 弄不明白微軟的那些程式設計師 所以,在執行 fd close 之時,應該先等待最後乙個 fd rea...