#define NETWORK_EVENT WM_USER+166 file://定义网络事件 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, LPARAM lParam); file://异步事件回调函数 … }; |
ON_MESSAGE(NETWORK_EVENT,OnNetEvent) |
BOOL CSocketSeverDlg::InitNetwork() { WSADATA wsaData; file://初始化TCP协议 BOOL ret = WSAStartup(MAKEWORD(2,2), &wsaData); if(ret != 0) { MessageBox("初始化网络协议失败!"); return FALSE; } file://创建服务器端套接字 ServerSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(ServerSock == INVALID_SOCKET) { MessageBox("创建套接字失败!"); closesocket(ServerSock); WSACleanup(); return FALSE; } file://绑定到本地一个端口上 sockaddr_in localaddr; localaddr.sin_family = AF_INET; localaddr.sin_port = htons(8888); file://端口号不要与其他应用程序冲突 localaddr.sin_addr.s_addr = 0; if(bind(ServerSock ,(struct sockaddr*)&localaddr,sizeof(sockaddr)) = = SOCKET_ERROR) { MessageBox("绑定地址失败!"); closesocket(ServerSock); WSACleanup(); return FALSE; } file://将SeverSock设置为异步非阻塞模式,并为它注册各种网络异步事件,其 中 m_hWnd file://为应用程序的主对话框或主窗口的句柄 if(WSAAsyncSelect(ServerSock, m_hWnd, NETWORK_EVENT, FD_ACCEPT | FD_CLOSE | FD_READ | FD_WRITE) == SOCKET_ERROR) { MessageBox("注册网络异步事件失败!"); WSACleanup(); return FALSE; } listen(ServerSock, 5); file://设置侦听模式 return TRUE; } |
void CSocketSeverDlg::OnNetEvent(WPARAM wParam, LPARAM lParam) { 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; } } |
void CSocketSeverDlg::OnAccept(SOCKET CurSock) { file://接受连接请求,并保存与发起连接请求的客户端进行通信Socket file://为新的socket注册异步事件,注意没有Accept事件 } void CSocketSeverDlg::OnClose(SOCET CurSock) { file://结束与相应的客户端的通信,释放相应资源 } void CSocketSeverDlg::OnSend(SOCET CurSock) { file://在给客户端发数据时做相关预处理 } void CSocketSeverDlg::OnReceive(SOCET CurSock) { file://读出网络缓冲区中的数据包 } |
void CSocketClntDlg::OnConnect(SOCKET CurSock, int error) { if(0 = = error) { if(CurSock = = ClntSock) MessageBox("连接服务器成功!"); } } |