WSAEVENTSELECT简单篇 之WINDOWS网络IO模型(事件选择模型)

WSAEVENTSELECT模型,局限性很大受WINDOWS操作系统限制WSA_MAXIMUM_WAIT_EVENTS最大为64!也就是连接超过64就需要重新开启新的线程去执行!以下是简单版最大支持64个连接!只是一个简单学习的例子VS2005测试通过!其模型设计难度也比较大!不是非常推荐使用!目前5种模型中各有所长!我还在寻找它的优点!希望有知道的人能留言告诉我嘿嘿!
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wData;
 WSAStartup(MAKEWORD(2,2),&wData);
WSAEVENT eventArray[WSA_MAXIMUM_WAIT_EVENTS];
 SOCKET sockArray[WSA_MAXIMUM_WAIT_EVENTS];
 int nEventToal=0;
 USHORT nPort=4567;//Sever's Port Number
 SOCKET sListen=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
 sockaddr_in sin;
 memset(&sin,0,sizeof(sin));
 sin.sin_family=AF_INET;
 sin.sin_port=htons(nPort);
 sin.sin_addr.S_un.S_addr=INADDR_ANY;
 if(::bind(sListen,(sockaddr*)&sin,sizeof(sockaddr))==SOCKET_ERROR){ //if binding error then reutrn the function
  std::cout<<"Failed Bind() \n"<<std::endl;
  return -1;
 }
 ::listen(sListen,16);
 WSAEVENT events=::WSACreateEvent(); //create event's object into socket
 ::WSAEventSelect(sListen,events,FD_ACCEPT|FD_CLOSE);
 eventArray[nEventToal]=events;
 sockArray[nEventToal]=sListen;
 ++nEventToal;
 while(TRUE){
  int nIndex=::WSAWaitForMultipleEvents(nEventToal,eventArray,FALSE,WSA_INFINITE,FALSE);
  nIndex=nIndex-WSA_WAIT_EVENT_0;
  for(int i=nIndex;i<nEventToal;i++){
   nIndex=::WSAWaitForMultipleEvents(1,&eventArray[i],TRUE,1000,FALSE);
   if(nIndex==WSA_WAIT_FAILED||nIndex==WSA_WAIT_TIMEOUT)
    continue;
   else{
    WSANETWORKEVENTS eventWork;
    ::WSAEnumNetworkEvents(sockArray[i],eventArray[i],&eventWork);
    if(eventWork.lNetworkEvents & FD_ACCEPT){
     if(eventWork.iErrorCode[FD_ACCEPT_BIT]==0){
      if(nEventToal>WSA_MAXIMUM_WAIT_EVENTS){
       std::cout<<"Too many connection!\n"<<std::endl;
       continue;
      }
      SOCKET sNew=::accept(sockArray[i],NULL,NULL);
      WSAEVENT eventClient=::WSACreateEvent();
      WSAEventSelect(sNew,eventClient,FD_READ|FD_CLOSE|FD_WRITE);
      eventArray[nEventToal]=eventClient;
      sockArray[nEventToal]=sNew;
      ++nEventToal;
      std::cout<<"登陆1个人进来了"<<std::endl;
     }
    }else if(eventWork.lNetworkEvents & FD_READ)
    {
     if(eventWork.iErrorCode[FD_READ_BIT]==0){
      char szText[256];
      int nRecv=::recv(sockArray[i],szText,strlen(szText),0);
      if(nRecv>0)
      {
       szText[nRecv]='\0';
       std::cout<<szText<<std::endl;
      }
     }
    }else if(eventWork.lNetworkEvents & FD_CLOSE){
     if(eventWork.iErrorCode[FD_CLOSE_BIT]==0){
      std::cout<<"退出了哦"<<std::endl;
      ::closesocket(sockArray[i]);
      for(int j=i;j<nEventToal-1;++j){
       sockArray[j]=sockArray[j+1];
       eventArray[j]=eventArray[j+1];
      }
      eventArray[nEventToal]=0;
      sockArray[nEventToal]=0;
      --nEventToal;
     }
    }else if(eventWork.lNetworkEvents &FD_WRITE){
    }
   }
  }
 }

 WSACleanup();
 return 0;
}

你可能感兴趣的:(WSAEVENTSELECT简单篇 之WINDOWS网络IO模型(事件选择模型))