對於許多初學者來說
同步方式指的是發送方不等接收方響應
阻塞套接字是指執行此套接字的網絡調用時
對於這些概念
MFC提供了一個異步類CAsyncSocket
為了簡單起見
先做服務器端應用程序
用MFC向導做一個基於對話框的應用程序SocketSever
在SocketSeverDlg
#define NETWORK_EVENT WM_USER+
SOCKET ServerSock; file://服務器端Socket
在類定義中增加如下定義
class CSocketSeverDlg : CDialog
{
…
public:
SOCKET ClientSock[CLNT_MAX_NUM]; file://存儲與客戶端通信的Socket的數組
/*各種網絡異步事件的處理函數*/
void OnClose(SOCKET CurSock); file://對端Socket斷開
void OnSend(SOCKET CurSock); file://發送網絡數據包
void OnReceive(SOCKET CurSock); file://網絡數據包到達
void OnAccept(SOCKET CurSock); file://客戶端連接請求
BOOL InitNetwork(); file://初始化網絡函數
void OnNetEvent(WPARAM wParam
…
};
在SocketSeverDlg
ON_MESSAGE(NETWORK_EVENT
定義初始化網絡函數
BOOL CSocketSeverDlg::InitNetwork()
{
WSADATA wsaData;
file://初始化TCP協議
BOOL ret = WSAStartup(MAKEWORD(
if(ret !=
{
MessageBox(
return FALSE;
}
file://創建服務器端套接字
ServerSock = socket(AF_INET
if(ServerSock == INVALID_SOCKET)
{
MessageBox(
closesocket(ServerSock);
WSACleanup();
return FALSE;
}
file://綁定到本地一個端口上
sockaddr_in localaddr;
localaddr
localaddr
localaddr
if(bind(ServerSock
= = SOCKET_ERROR)
{
MessageBox(
closesocket(ServerSock);
WSACleanup();
return FALSE;
file://將SeverSock設置為異步非阻塞模式
file://為應用程序的主對話框或主窗口的句柄
if(WSAAsyncSelect(ServerSock
FD_ACCEPT | FD_CLOSE | FD_READ | FD_WRITE) == SOCKET_ERROR)
{
MessageBox(
WSACleanup();
return FALSE;
}
listen(ServerSock
return TRUE;
}
下面定義網絡異步事件的回調函數
void CSocketSeverDlg::OnNetEvent(WPARAM wParam
{
file://調用Winsock API函數
int iEvent = WSAGETSELECTEVENT(lParam);
file://調用Winsock API函數
SOCKET CurSock= (SOCKET)wParam;
switch(iEvent)
{
case FD_ACCEPT: file://客戶端連接請求事件
OnAccept(CurSock);
break;
case FD_CLOSE: file://客戶端斷開事件:
OnClose(CurSock);
break;
case FD_READ: file://網絡數據包到達事件
OnReceive(CurSock);
break;
case FD_WRITE: file://發送網絡數據事件
OnSend(CurSock);
break;
default: break;
}
}
以下是發生在相應Socket上的各種網絡異步事件的處理函數
void CSocketSeverDlg::OnAccept(SOCKET CurSock)
{
file://接受連接請求
file://為新的socket注冊異步事件
}
void CSocketSeverDlg::OnClose(SOCET CurSock)
{
file://結束與相應的客戶端的通信
}
void CSocketSeverDlg::OnSend(SOCET CurSock)
{
file://在給客戶端發數據時做相關預處理
}
void CSocketSeverDlg::OnReceive(SOCET CurSock)
{
file://讀出網絡緩沖區中的數據包
}
用同樣的方法建立一個客戶端應用程序
void CSocketClntDlg::OnConnect(SOCKET CurSock
{
if(
{
if(CurSock = = ClntSock)
MessageBox(
}
}
定義OnReceive()函數
定義OnSend()函數
定義OnClose()函數
以上就是用基於Windows消息機制的異步I/O模型做服務器和客戶端應用程序的基本方法
在實現了上面的例子後
From:http://tw.wingwit.com/Article/program/net/201311/13815.html