封装WSAEventSelect模型

 

  1. #include <winsock2.h>
  2. #include <process.h>
  3. #pragma comment(lib,"ws2_32.lib")
  4. #pragma once
  5. class CAsyncHandler
  6. {
  7. public:
  8.     CAsyncHandler()
  9.     {
  10.     }
  11.     virtual ~CAsyncHandler()
  12.     {
  13.     }
  14.     virtual int AcceptNotify( SOCKET hSocket, const char *strClientIP, unsigned short usClientPort )= 0;
  15. };
  16. class CAsynch_Event_Handler
  17. {
  18. public:
  19.     CAsynch_Event_Handler(void);
  20.     ~CAsynch_Event_Handler(void);
  21.     int Start(CAsyncHandler * phEvent, UINT unPort);
  22.     int Stop(void);
  23. protected:
  24.     static unsigned int  __stdcall AcceptThread(void * lpParam);
  25.     unsigned int  AcceptThreadProc();
  26. private:
  27.     SOCKET  m_hListenSocket;
  28.     HANDLE  m_hIOThread;
  29.     HANDLE  m_hExitThread;
  30.     CAsyncHandler *m_pEventHandler;
  31. private:
  32.     int OnAccept(); 
  33.     BOOL InitSocket()
  34.     {
  35.         WORD wVersionRequested;
  36.         WSADATA wsaData;
  37.         int err;
  38.         wVersionRequested = MAKEWORD( 2, 2 );
  39.         err = WSAStartup( wVersionRequested, &wsaData );
  40.         if ( err != 0 )
  41.         {
  42.             /* Tell the user that we could not find a usable */
  43.             /* WinSock DLL. 
  44.             */
  45.             return FALSE;
  46.         }
  47.         /* Confirm that the WinSock DLL supports 2.2.*/
  48.         /* Note that if the DLL supports versions greater    */
  49.         /* than 2.2 in addition to 2.2, it will still return */
  50.         /* 2.2 in wVersion since that is the version we      */
  51.         /* requested.                                        */
  52.         if ( LOBYTE( wsaData.wVersion ) != 2 ||
  53.             HIBYTE( wsaData.wVersion ) != 2 )
  54.         {
  55.             /* Tell the user that we could not find a usable */
  56.             /* WinSock DLL.                                  */
  57.             WSACleanup( );
  58.             return FALSE; 
  59.         }
  60.         return TRUE;
  61.     };
  62.     BOOL ClearSocket()
  63.     {
  64.         WSACleanup( );
  65.         return TRUE;
  66.     };
  67. };
  68. ///*************** CPP*****************//
  69. #include "StdAfx.h"
  70. #include "Asynch_Event_Handler.h"
  71. #include <iostream>
  72. using namespace std;
  73. CAsynch_Event_Handler::CAsynch_Event_Handler(void)
  74. {
  75.     m_hListenSocket = INVALID_SOCKET;
  76. }
  77. CAsynch_Event_Handler::~CAsynch_Event_Handler(void)
  78. {
  79. }
  80. int CAsynch_Event_Handler::Start(CAsyncHandler * phEvent, UINT unPort)
  81. {
  82.     if( m_hListenSocket != INVALID_SOCKET )
  83.     {
  84.         return 0;
  85.     }
  86.     InitSocket();
  87.     m_pEventHandler = phEvent;
  88.     struct sockaddr_in serverAddress;
  89.     int     err;
  90.     m_hListenSocket = socket(AF_INET, SOCK_STREAM, 0);
  91.     if( INVALID_SOCKET == m_hListenSocket )
  92.     {
  93.         err = WSAGetLastError();
  94.         return err;
  95.     }
  96.     memset(&serverAddress, 0, sizeof(serverAddress));
  97.     serverAddress.sin_family      = AF_INET;
  98.     serverAddress.sin_addr.s_addr = 0;
  99.     serverAddress.sin_port   = htons( unPort );
  100.     err = bind(m_hListenSocket,
  101.         (struct sockaddr *)&serverAddress,
  102.         sizeof(serverAddress)
  103.         );
  104.     if( err == SOCKET_ERROR )
  105.     {
  106.         err = WSAGetLastError();
  107.         closesocket( m_hListenSocket );
  108.         m_hListenSocket = INVALID_SOCKET;
  109.         return err;
  110.     }
  111.     err = listen( m_hListenSocket, SOMAXCONN );
  112.     if( err == SOCKET_ERROR )
  113.     {
  114.         err = WSAGetLastError();
  115.         closesocket( m_hListenSocket );
  116.         m_hListenSocket = INVALID_SOCKET;
  117.         return err;
  118.     }
  119.     m_hExitThread = CreateEvent( NULL, TRUE, FALSE, NULL );
  120.     m_hIOThread = (HANDLE
  121.         _beginthreadex(
  122.         NULL,
  123.         0,
  124.         AcceptThread,
  125.         this,
  126.         0,
  127.         0 );
  128.     return 0;
  129. }
  130. int CAsynch_Event_Handler::Stop(void)
  131. {
  132.     if(  INVALID_SOCKET == m_hListenSocket )
  133.     {
  134.         return 0;
  135.     }
  136.     closesocket( m_hListenSocket );
  137.     m_hListenSocket = INVALID_SOCKET;
  138.     SetEvent( m_hExitThread );
  139.     if( WAIT_TIMEOUT == WaitForSingleObject( m_hIOThread, 10000 ) )
  140.     {
  141.         TerminateThread( m_hIOThread, 1 );
  142.     }
  143.     CloseHandle( m_hExitThread );
  144.     CloseHandle( m_hIOThread );
  145.     ClearSocket();
  146.     return 0;
  147. }
  148. unsigned int  CAsynch_Event_Handler::AcceptThreadProc()
  149. {
  150.     WSANETWORKEVENTS Events;
  151.     WSAEVENT hWaitAll[WSA_MAXIMUM_WAIT_EVENTS] = { INVALID_HANDLE_VALUE };  
  152.     hWaitAll[0] = m_hExitThread;
  153.     hWaitAll[1] = WSACreateEvent();
  154.     WSAEventSelect(
  155.         m_hListenSocket,
  156.         hWaitAll[1],
  157.         FD_ACCEPT );
  158.     int nWaitCounts = 2;
  159.     while( TRUE )
  160.     {
  161.         DWORD wt = WSAWaitForMultipleEvents(
  162.             nWaitCounts,
  163.             hWaitAll,
  164.             FALSE,
  165.             INFINITE,
  166.             TRUE );
  167.         if( wt == WAIT_OBJECT_0 )
  168.         {
  169.             //退出线程
  170.             break;
  171.         }
  172.         DWORD index = wt - WSA_WAIT_EVENT_0;
  173.         if( index == 1 )
  174.         {
  175.             int nResult = WSAEnumNetworkEvents(
  176.                 m_hListenSocket,
  177.                 hWaitAll[1],
  178.                 &Events);
  179.             if( 0 == nResult )
  180.             {
  181.                 //接受
  182.                 if( Events.lNetworkEvents & FD_ACCEPT ) 
  183.                 {
  184.                     if( SOCKET_ERROR == Events.iErrorCode[FD_ACCEPT_BIT] )
  185.                     {
  186.                         continue;
  187.                     }
  188.                     else
  189.                     {
  190.                         //接受连接 
  191.                         OnAccept();
  192.                     }
  193.                 }
  194.             }
  195.         }
  196.         else if( wt == WAIT_IO_COMPLETION )
  197.         {
  198.             continue;
  199.         }
  200.         else 
  201.         {
  202.             break;
  203.         }
  204.     }
  205.     return 0;
  206. }
  207. unsigned int  __stdcall CAsynch_Event_Handler::AcceptThread(void * lpParam)
  208. {
  209.     CAsynch_Event_Handler *pAcceptor = (CAsynch_Event_Handler *)lpParam;
  210.     return pAcceptor->AcceptThreadProc();
  211. }
  212.     
  213. int CAsynch_Event_Handler::OnAccept()
  214. {
  215.     SOCKET AcceptSocket;
  216.     struct sockaddr_in clientAddress;
  217.     int clientAddrLen = sizeof(sockaddr_in);
  218.     AcceptSocket = accept( m_hListenSocket, (sockaddr *)&clientAddress, &clientAddrLen );
  219.     if( INVALID_SOCKET == AcceptSocket )
  220.     {
  221.         return WSAGetLastError();
  222.     }
  223.     else
  224.     {
  225.         DWORD nValue = 1;
  226.         int nLen = sizeof( nValue );
  227.         if( SOCKET_ERROR == setsockopt( AcceptSocket, IPPROTO_TCP ,TCP_NODELAY, (char *)&nValue, nLen ) )
  228.         {
  229.             int err = WSAGetLastError();
  230.         }
  231.         
  232.         nValue = 16384;
  233.         if( SOCKET_ERROR == setsockopt( AcceptSocket, SOL_SOCKET ,SO_SNDBUF, (char *)&nValue, nLen ) )
  234.         {
  235.             int err = WSAGetLastError();
  236.         }
  237.         if( SOCKET_ERROR == setsockopt( AcceptSocket, SOL_SOCKET ,SO_RCVBUF, (char *)&nValue, nLen ) )
  238.         {
  239.             int err = WSAGetLastError();
  240.         }
  241.         m_pEventHandler->AcceptNotify( AcceptSocket, inet_ntoa( clientAddress.sin_addr ), ntohs( clientAddress.sin_port )  );
  242.         return 0;
  243.     }
  244. }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值