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