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