複製鏈接
請複製以下鏈接發送給好友

非阻塞模式

鎖定
非阻塞模式是指利用socket事件的消息機制,Server端與Client端之間的通信處於異步狀態。
中文名
非阻塞模式
利    用
socket事件的消息機制
消息參數
wParam是socket的句柄
lParam
socket事件

目錄

非阻塞模式簡介

在非阻塞模式下利用socket事件的消息機制,Server端與Client端之間的通信處於異步狀態下。通常需要從CSocket類派生一個新類,派生新類的目的是重載socket事件的消息函數,然後在socket事件的消息函數中添入合適的代碼以完成Client端與Server端之間的通信,與阻塞模式相比,非阻塞模式無需創建一個新線程。
這裏將討論當Server端socket事件-FD_ACCEPT被觸發後,該事件的處理函數OnAccept是如何進一步被觸發的。其它事件的處理函數如OnConnect,OnReceive等的觸發方式與此類似。在1中已提到Client/Server端通信時,Server端socket正在接收來自Client端socket連接請求,這將會觸發FD_ACCEPT事件,同時Server端的網絡傳輸服務進程向Server端的socketwindow(CSocketWnd)發送事件通知消息WM_SOCKET_NOTIFY,通知有FD_ACCEPT事件產生,CsocketWnd在收到事件通知消息後,調用消息處理函數OnSocketNotify:
LRESULTCSocketWnd::OnSocketNotify(WPARAMwParam,LPARAMlParam)
{
CSocket::AuxQueueAdd(WM_SOCKET_NOTIFY,wParam,lParam);
CSocket::ProcessAuxQueue();
return0L;
}

非阻塞模式參數

消息參數wParam是socket的句柄,lParam是socket事件。這裏稍作解釋一下,CSocketWnd類是作為CSocket類的友元類,這意味着它可以訪問CSocket類中的保護和私有成員函數和變量,AuxQueueAdd和ProcessAuxQueue是CSocket類的靜態成員函數,如果你對友元不熟悉,請迅速找本有關C 書看一下友元的使用方法吧!
ProcessAuxQueue是實質處理socket事件的函數,在該函數中有這樣一句代碼:
CAsyncSocket*pSocket=CAsyncSocket::LookupHandle((SOCKET)wParam,TRUE);
其實也就是由socket句柄得到發送事件通知消息的socket指針pSocket:從m_pmapSocketHandle中查找(見1)!
最後,WSAGETSELECTEVENT(lParam)會取出事件類型,在一個簡單的switch語句中判斷事件類型並調用事件處理函數。在這裏,事件類型是FD_ACCEPT,當然就調用pSocket->OnAccept!

非阻塞模式結束語

Server端socket處於阻塞調用模式下,它必須在一個新創建的線程中工作,防止主線程被阻塞。
當有多個Client端socket與Server端socket連接及通信時,Server端採用阻塞模式就顯得不適合了,應該採用非阻塞模式,利用socket事件的消息機制來接受多個Client端socket的連接請求並進行通信。
在非阻塞模式下,利用CSocketWnd作為所有sockets的消息池,是實現socket事件的消息機制的關鍵技術。

非阻塞模式註釋

當前模塊狀態——用於保存當前線程和模塊狀態的一個結構,可以通過AfxGetThreadModule()獲得。AFX_MODULE_THREAD_STATE在CSocket重新定義為_AFX_SOCK_THREAD_STATE。
socket類型——在TCP/IP協議中,Client/Server網絡程序採用TCP協議:即socket類型為SOCK_STREAM,它是可靠的連接方式。在這裏不採用UDP協議:即socket類型為SOCK_DGRAM,它是不可靠的連接方式。