WinSock WSAEventSelect 服务端模型 (单线程)

#include "stdafx.h"
#include <Winsock2.h>

#pragma comment(lib,"Ws2_32.lib")

void InitSocket()
{
 WORD wVersionRequested;
 WSADATA wsaData;
 int err;
 
 wVersionRequested = MAKEWORD( 2, 2 );
 
 err = WSAStartup( wVersionRequested, &wsaData );
 if ( err != 0 ) {
  /* Tell the user that we could not find a usable */
  /* WinSock DLL.                                  */
  return;
 }
 
 /* Confirm that the WinSock DLL supports 2.2.*/
 /* Note that if the DLL supports versions greater    */
 /* than 2.2 in addition to 2.2, it will still return */
 /* 2.2 in wVersion since that is the version we      */
 /* requested.                                        */
 
 if ( LOBYTE( wsaData.wVersion ) != 2 ||
   HIBYTE( wsaData.wVersion ) != 2 ) {
  /* Tell the user that we could not find a usable */
  /* WinSock DLL.                                  */
  WSACleanup( );
  return;
 }
}

int _tmain(int argc, _TCHAR* argv[])
{
 InitSocket();
 
 WSAEVENT eventArray[WSA_MAXIMUM_WAIT_EVENTS];
 SOCKET socketArray[WSA_MAXIMUM_WAIT_EVENTS];
 int TotalSockets=0;

 SOCKET sListen=socket(AF_INET,SOCK_STREAM,0);
 if(INVALID_SOCKET==sListen)
 {
  printf("创建socket失败");
  ::WSACleanup();
  return 0;
 }
 ::sockaddr_in addr;
 addr.sin_family=AF_INET;
 addr.sin_port=htons(3456);
 addr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
 if( SOCKET_ERROR==bind(sListen,(sockaddr*)&addr,sizeof(sockaddr)))
 {
  printf("绑定失败");
  ::WSACleanup();
  return 0;
 }
 listen(sListen,5);
 WSAEVENT e=WSACreateEvent();
 WSAEventSelect(sListen,e,FD_ACCEPT);
 eventArray[TotalSockets]=e;
 socketArray[TotalSockets]=sListen;
 TotalSockets++;
 while(true)
 {
  int nIndex=::WSAWaitForMultipleEvents(TotalSockets,eventArray,false,WSA_INFINITE,false);
  nIndex=nIndex-WSA_WAIT_EVENT_0;
  for(int i=nIndex;i<TotalSockets;i++)
  {
   nIndex=::WSAWaitForMultipleEvents(1,&eventArray[i],true,1000,false);
   if(nIndex==WSA_WAIT_TIMEOUT || nIndex== WSA_WAIT_FAILED)
   {
    continue;
   }
   else
   {
    WSANETWORKEVENTS wsaEvent;
    ::WSAEnumNetworkEvents(socketArray[i],eventArray[i],&wsaEvent);
    if(wsaEvent.lNetworkEvents&FD_ACCEPT)
    {
     if(wsaEvent.iErrorCode[FD_ACCEPT_BIT]==0)
     {
      if(TotalSockets>WSA_MAXIMUM_WAIT_EVENTS)
      {
       printf("too many connections/n");
       continue;
      }
      ::sockaddr_in clientaddr;
      int len=sizeof(sockaddr_in);
      SOCKET client=accept(socketArray[i],(sockaddr*)&clientaddr,&len);
      if(INVALID_SOCKET == client)
      {
       printf("连接不可用/n");
       continue;
      }
      eventArray[TotalSockets]=::WSACreateEvent();
      socketArray[TotalSockets]=client;
      ::WSAEventSelect(client,eventArray[TotalSockets],FD_READ |FD_CLOSE);
      TotalSockets++;
      printf("新连接:%s/n",inet_ntoa(clientaddr.sin_addr));
     }
    }
    else if(wsaEvent.lNetworkEvents&FD_READ)
    {
     if(wsaEvent.iErrorCode[FD_READ_BIT]==0)
     {
      char *buf=new char[1024];
      int Ret=recv(socketArray[i],buf,1024,0);
      if(Ret>0)
      {
       buf[Ret]='/0';
       printf("接到数据:%s/n",buf);
      }
      delete[]buf;
     }
    }
    else if(wsaEvent.lNetworkEvents&FD_CLOSE)
    {
     ::closesocket(socketArray[i]);
     for(int j=i;j<TotalSockets-1;j++)
     {
      socketArray[j]=socketArray[j+1];
      eventArray[j]=eventArray[j+1];
     }
     printf("一连接继开/n");
     TotalSockets--;
    }
   }
  }
 }
 return 0;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值