(1) h文件中声明网络事件响应函数
afx_msg void OnNetEvent(WPARAM wParam, LPARAM lParam);
(2)cpp文件中把NETWORK_EVENT事件映射到OnNetEvent()函数
BEGIN_MESSAGE_MAP(CInstrumentStatusView, CFormView) ON_MESSAGE(NETWORK_EVENT,OnNetEvent) END_MESSAGE_MAP()
(3)OnNetEvent()函数体, 对FD_CONNECT, FD_CLOSE, FD_READ事件进行响应处理
void CInstrumentStatusView::OnNetEvent(WPARAM wParam, LPARAM lParam) { int iEvent = WSAGETSELECTEVENT(lParam); int error = WSAGETSELECTERROR(lParam); //if error!=0, it means failure SOCKET CurSock= (SOCKET)wParam; if(error) { AfxMessageBox("OnNetEvent()接收到错误消息"); closesocket(wParam); return; } switch(iEvent){ case FD_CONNECT: OnSockConnect(error); //void CInstrumentStatusView::OnSockConnect(int error); break; case FD_CLOSE: CloseCurrSockHandle();//void CInstrumentStatusView::CloseCurrSockHandle(); break; case FD_READ: OnSockReceive(); //recv buffer and copy to m_pCurCommand->m_CommandBuffer break; } }
(4)创建套接字, 并使用WSAAsyncSelect()为套接字m_sockClient注册事件
if(WSAAsyncSelect(m_sockClient,m_hWnd,NETWORK_EVENT,FD_CLOSE | FD_READ | FD_CONNECT) == SOCKET_ERROR) { closesocket(m_sockClient); //MessageBox("CComWnd注册网络异步事件失败!"); //WSACleanup(); return 0; }
(5)OnSockReceive()函数体, 收到FD_READ消息后, 执行此函数
void CInstrumentStatusView::OnSockReceive(){ int ReadResults=0; BOOL Ready=FALSE; char tempChar; WSAAsyncSelect(m_sockClient,m_hWnd,NETWORK_EVENT,0); //关闭套接字事件m_sockClient上的事件 //循环读,每次读一个字节 //while(total!=m_pCurCommand->m_nExpectedBytes) while(!Ready) //当读到结束符时,Ready=TRUE { ReadResults=recv(m_sockClient,&tempChar,1,0); if(ReadResults == SOCKET_ERROR)//recv返回异常处理 { if (WSAEWOULDBLOCK == WSAGetLastError()) { continue; //如果异常是"阻塞异常", 继续下次循环 } else //非WSAEWOULDBLOCK 异常的处理,可能是网络断开等 { m_bConnected=FALSE; break; } } else if(ReadResults==0) { AfxMessageBox(_T("对端关闭了连接")); } else if(ReadResults==1) { if(m_pCurCommand->AddToReceiveBuffer(tempChar)) Ready=TRUE; //AddToReceiveBuffer中判断tempChar是否是结束字符,如果是,返回TRUE, while循环条件Ready置为TRUE,退出循环 } } WSAAsyncSelect(m_sockClient,m_hWnd,NETWORK_EVENT,FD_CLOSE | FD_READ | FD_CONNECT);//数据接收完成,恢复套接字m_sockClient的网络事件 }