Windows異步套接字(WSASocket)


異步套接字:
如果使用阻塞的套接字的話,在控制台下還好!如果是WIN32程序的話,那么就容易造成界面的假死,因為接收函數一直等待有消息進來之后才會被返回!所以此時界面一直屬於假死的狀態,如果你亂動的話,那么就容易真死了。解決辦法如下:
第一:使用多線程技術,多線程和SOCKET結合的話,可以使用單獨一個線程來接收消息。這樣即使接收函數阻塞了也不會影響其他線程,例如界面線程。但是如果使用多線程的話,就必須要考慮到多線程之間同步的問題,以及臨界資源的問題。
 
第二:使用異步套接字。但是使用異步套接字的話,至少要了解一下Windows的消息機制。異步套接字的工作原理是基於Windows消息的,和在MFC中的其他消息函數一樣,當有消息的時候,套接字的相關函數就被觸發。例如,我們雙擊的時候,系統感知了這個消息,然后做出響應。異步套接字的工作也是如此,當有網絡消息來的時候,接收函數才工作,否則接收函數是不工作的。
 
使用步驟如下:
WSADATA wsaData;
WORD wVersion = MAKEWORD(2,2);
//需要打開版本為2.2的socket
if ( WSAStartup(wVersion,&wsaData) != 0 )
{
//打開失敗…
}
//判斷版本是否為2.2
if ( 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消息驅動結合起來了,但是用起來真的很方便,相比多線程節省了許多其他的步驟。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM