標籤:style blog color io os 使用 ar sp div
非同步通訊端:如果使用阻塞的通訊端的話,在控制台下還好!如果是WIN32程式的話,那麼就容易造成介面的假死,因為接收函數一直等待有訊息進來之後才會被返回!所以此時介面一直屬於假死的狀態,如果你亂動的話,那麼就容易真死了。解決辦法如下:第一:使用多線程技術,多線程和SOCKET結合的話,可以使用單獨一個線程來接收訊息。這樣即使接收函數阻塞了也不會影響其他線程,例如介面線程。但是如果使用多線程的話,就必須要考慮到多線程之間同步的問題,以及臨界資源的問題。 第二:使用非同步通訊端。但是使用非同步通訊端的話,至少要瞭解一下Windows的訊息機制。非同步通訊端的工作原理是基於Windows訊息的,和在MFC中的其他訊息函數一樣,當有訊息的時候,通訊端的相關函數就被觸發。例如,我們雙擊的時候,系統感知了這個訊息,然後做出響應。非同步通訊端的工作也是如此,當有網路訊息來的時候,接收函數才工作,否則接收函數是不工作的。 使用步驟如下:
WSADATA wsaData;WORD wVersion = MAKEWORD(2,2);//需要開啟版本為2.2的socketif ( WSAStartup(wVersion,&wsaData) != 0 ){//開啟失敗…}//判斷版本是否為2.2if ( LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2 ) {WSACleanup();} //其實代碼都是一樣的,只是變成了WSA***函數而已!SOCKET m_ClientSocket;m_ClientSocket = WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,0);if ( m_ServerSocket == INVALID_SOCKET ){MessageBox("建立通訊端失敗...");} //註冊網路事件//其實這個函數是關鍵,首先說一下,最後一個參數是FD_READ其實//還有如下的參數可以填寫://Event: FD_ACCEPT//Event: FD_ADDRESS_LIST_CHANGE//Event: FD_GROUP_QOS//Event: FD_OOB//Event: FD_QOS//Event: FD_READ//Event: FD_WRITE//這個函數叫註冊訊息,意思就是如果m_ClientSocket接收到了訊息//的話就發送UM_RECVMESSAGE這個訊息,為什麼是接收到了訊息//呢?因為註冊的是FD_READ啊,如果註冊了FD_ACCEPT那麼就是有//人請求串連的時候就發送**訊息if( SOCKET_ERROR==WSAAsyncSelect(m_ClientSocket,m_hWnd,UM_RECVMESSAGE,FD_READ) ){//註冊失敗.} //接收函式宣告!但是此聲明函數一定要寫到//DECLARE_MESSAGE_MAP()之前,因為這個函數要作為訊息路由//中的函數處理,說白了,這個函數的調用是通過訊息映射來調用的afx_msg LRESULT OnServerRecvMessage(WPARAM wParam,LPARAM lParam);DECLARE_MESSAGE_MAP() //接收函數定義!定義完了,上面也聲明完了,但是怎麼調用呢!LRESULT CServerDlg::OnServerRecvMessage(WPARAM wParam,LPARAM lParam){switch ( LOWORD(lParam) ){case FD_READ:}return 0;} //這個就是訊息路由的建立了,一定要寫到兩個宏之間,呵呵,前幾天剛看完侯俊傑的MFC,所以覺得這個特別精髓,我記得我在寫代碼的時候我居然寫到了另外一個類中,還好我明白原理,2分鐘就找到錯誤了,如果要是以前的話,估計沒有幾天找不到。哈哈BEGIN_MESSAGE_MAP(XX子類,XX父類)ON_MESSAGE(UM_RECVMESSAGE,&XX子類:OnServerRecvMessage)END_MESSAGE_MAP()
整理下思路,上面,註冊了FD_READ訊息。如果某個SOCKET變數收到了訊息的話,就發送UM_RECVMESSAGE訊息,並且我們關聯了ON_MESSAGE(UM_RECVMESSAGE,&XX子類:OnServerRecvMessage)這個訊息,所以發出UM_RECVMESSAGE訊息之後,就調用OnServerRecvMessage這個函數了,這個函數就是接收訊息,然後處理就可以了! 其實就等於是把SOCKET和WINDOWS訊息驅動結合起來了,但是用起來真的很方便,相比多線程節省了許多其他的步驟。
Windows非同步通訊端(WSASocket)