Scoket异步套接字编程,在客户端实现数据的发送和接收

 

WSAAsyncSelect模型 实现socket客户端接收数据的例子

 

(1) h文件中声明网络事件响应函数

[cpp] view plaincopy
 
  1. afx_msg void OnNetEvent(WPARAM wParam, LPARAM lParam);  

(2)cpp文件中把NETWORK_EVENT事件映射到OnNetEvent()函数

[cpp] view plaincopy
 
  1. BEGIN_MESSAGE_MAP(CInstrumentStatusView, CFormView)  
  2.     ON_MESSAGE(NETWORK_EVENT,OnNetEvent)  
  3. END_MESSAGE_MAP()  
 

(3)OnNetEvent()函数体, 对FD_CONNECT, FD_CLOSE, FD_READ事件进行响应处理

[cpp] view plaincopy
 
  1. void CInstrumentStatusView::OnNetEvent(WPARAM wParam, LPARAM lParam) {  
  2.     int iEvent = WSAGETSELECTEVENT(lParam);  
  3.     int error = WSAGETSELECTERROR(lParam); //if error!=0, it means failure   
  4.     SOCKET CurSock= (SOCKET)wParam;  
  5.     if(error)  
  6.     {  
  7.         AfxMessageBox("OnNetEvent()接收到错误消息");  
  8.         closesocket(wParam);  
  9.         return;  
  10.     }  
  11.     switch(iEvent){  
  12.     case FD_CONNECT:  
  13.              OnSockConnect(error); //void CInstrumentStatusView::OnSockConnect(int error);  
  14.         break;  
  15.           
  16.     case FD_CLOSE:  
  17.              CloseCurrSockHandle();//void CInstrumentStatusView::CloseCurrSockHandle();  
  18.         break;  
  19.           
  20.     case FD_READ:   
  21.              OnSockReceive();      //recv buffer and copy to m_pCurCommand->m_CommandBuffer  
  22.         break;  
  23.           
  24.     }  
  25.       
  26. }  
 

(4)创建套接字, 并使用WSAAsyncSelect()为套接字m_sockClient注册事件

[cpp] view plaincopy
 
  1. if(WSAAsyncSelect(m_sockClient,m_hWnd,NETWORK_EVENT,FD_CLOSE | FD_READ | FD_CONNECT) == SOCKET_ERROR)  
  2. {  
  3.     closesocket(m_sockClient);  
  4.     //MessageBox("CComWnd注册网络异步事件失败!");  
  5.     //WSACleanup();  
  6.     return 0;  
  7. }  
 

(5)OnSockReceive()函数体, 收到FD_READ消息后, 执行此函数

[cpp] view plaincopy
 
  1. void CInstrumentStatusView::OnSockReceive(){  
  2.     int ReadResults=0;  
  3.     BOOL Ready=FALSE;  
  4.     char tempChar;  
  5.     WSAAsyncSelect(m_sockClient,m_hWnd,NETWORK_EVENT,0); //关闭套接字事件m_sockClient上的事件  
  6.     //循环读,每次读一个字节  
  7.     //while(total!=m_pCurCommand->m_nExpectedBytes)  
  8.     while(!Ready) //当读到结束符时,Ready=TRUE  
  9.     {  
  10.         ReadResults=recv(m_sockClient,&tempChar,1,0);   
  11.         if(ReadResults == SOCKET_ERROR)//recv返回异常处理  
  12.         {  
  13.             if (WSAEWOULDBLOCK == WSAGetLastError())  
  14.             {  
  15.                 continue; //如果异常是"阻塞异常", 继续下次循环  
  16.             }  
  17.             else //非WSAEWOULDBLOCK 异常的处理,可能是网络断开等  
  18.             {  
  19.                 m_bConnected=FALSE;  
  20.                 break;  
  21.             }  
  22.         }  
  23.         else if(ReadResults==0)  
  24.         {  
  25.             AfxMessageBox(_T("对端关闭了连接"));  
  26.         }  
  27.         else if(ReadResults==1)  
  28.         {  
  29.             if(m_pCurCommand->AddToReceiveBuffer(tempChar)) Ready=TRUE;  
  30. //AddToReceiveBuffer中判断tempChar是否是结束字符,如果是,返回TRUE, while循环条件Ready置为TRUE,退出循环  
  31.         }  
  32.     }  
  33.     WSAAsyncSelect(m_sockClient,m_hWnd,NETWORK_EVENT,FD_CLOSE | FD_READ | FD_CONNECT);//数据接收完成,恢复套接字m_sockClient的网络事件  
  34.       
  35. }  
 
博客内容只为本人学习所感转载亦或自写,不足或错误之处请大家不吝赐教
原文地址:https://www.cnblogs.com/niupan369/p/4425195.html