2024年4月12日发(作者:)

#include

  #include

  #pragma comment(lib,"ws2_")

  #pragma once

  class CAsyncHandler

  {

  public:

  CAsyncHandler()

  {

  }

  virtual ~CAsyncHandler()

  {

  }

  virtual int AcceptNotify( SOCKET hSocket, const char *strClientIP, unsigned short usClientPort )= 0;

  };

  class CAsynch_Event_Handler

  {

  public:

  CAsynch_Event_Handler(void);

  ~CAsynch_Event_Handler(void);

  int Start(CAsyncHandler * phEvent, UINT unPort);

  int Stop(void);

  protected:

  static unsigned int __stdcall AcceptThread(void * lpParam);

  unsigned int AcceptThreadProc();

  private:

  SOCKET m_hListenSocket;

  HANDLE m_hIOThread;

  HANDLE m_hExitThread;

  CAsyncHandler *m_pEventHandler;

  private:

  int OnAccept();

  BOOL 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 FALSE;

  }

  /* 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( on ) != 2 ||

  HIBYTE( on ) != 2 )

  {

  /* Tell the user that we could not find a usable */

  /* WinSock DLL. */

  WSACleanup( );

  return FALSE;

  }

  return TRUE;

  };

  BOOL ClearSocket()

  {

  WSACleanup( );

  return TRUE;

  };

  };

  ///*************** CPP*****************//

  #include "StdAfx.h"

  #include "Asynch_Event_Handler.h"

  #include

  using namespace std;

  CAsynch_Event_Handler::CAsynch_Event_Handler(void)

  {

  m_hListenSocket = INVALID_SOCKET;

  }

  CAsynch_Event_Handler::~CAsynch_Event_Handler(void)

  {

  }

  int CAsynch_Event_Handler::Start(CAsyncHandler * phEvent, UINT unPort)

  {

  if( m_hListenSocket != INVALID_SOCKET )

  {

  return 0;

  }

  InitSocket();

  m_pEventHandler = phEvent;

  struct sockaddr_in serverAddress;

  int err;

  m_hListenSocket = socket(AF_INET, SOCK_STREAM, 0);

  if( INVALID_SOCKET == m_hListenSocket )

  {

  err = WSAGetLastError();

  return err;

  }

  memset(&serverAddress, 0, sizeof(serverAddress));

  _family = AF_INET;

  _addr.s_addr = 0;

  _port = htons( unPort );

  err = bind(m_hListenSocket,

  (struct sockaddr *)&serverAddress,

  sizeof(serverAddress)

  );

  if( err == SOCKET_ERROR )

  {

  err = WSAGetLastError();

  closesocket( m_hListenSocket );

  m_hListenSocket = INVALID_SOCKET;

  return err;

  }

  err = listen( m_hListenSocket, SOMAXCONN );

  if( err == SOCKET_ERROR )

  {

  err = WSAGetLastError();

  closesocket( m_hListenSocket );

  m_hListenSocket = INVALID_SOCKET;

  return err;}

  m_hExitThread = CreateEvent( NULL, TRUE, FALSE, NULL );

  m_hIOThread = (HANDLE)

  _beginthreadex(

  NULL,

  0,

  AcceptThread,

  this,

  0,

  0 );

  return 0;

  }

  int CAsynch_Event_Handler::Stop(void)

  {

  if( INVALID_SOCKET == m_hListenSocket )

  {

  return 0;

  }

  closesocket( m_hListenSocket );

  m_hListenSocket = INVALID_SOCKET;

  SetEvent( m_hExitThread );

  if( WAIT_TIMEOUT == WaitForSingleObject( m_hIOThread, 10000 ) )

  {

  TerminateThread( m_hIOThread, 1 );

  }

  CloseHandle( m_hExitThread );

  CloseHandle( m_hIOThread );

  ClearSocket();

  return 0;

  }

  unsigned int CAsynch_Event_Handler::AcceptThreadProc()

  {

  WSANETWORKEVENTS Events;

  WSAEVENT hWaitAll[WSA_MAXIMUM_WAIT_EVENTS] = { INVALID_HANDLE_VALUE };

  hWaitAll[0] = m_hExitThread;

  hWaitAll[1] = WSACreateEvent();

  WSAEventSelect(

  m_hListenSocket,

  hWaitAll[1],

  FD_ACCEPT );

  int nWaitCounts = 2;

  while( TRUE )

  {

  DWORD wt = WSAWaitForMultipleEvents(

  nWaitCounts,

  hWaitAll,

  FALSE,

  INFINITE,

  TRUE );

  if( wt == WAIT_OBJECT_0 )

  {

  //退出线程

  break;

  }

  DWORD index = wt - WSA_WAIT_EVENT_0;

  if( index == 1 )

  {

  int nResult = WSAEnumNetworkEvents(

  m_hListenSocket,

  hWaitAll[1],

  &Events);

  if( 0 == nResult )

  {

  //接受

  if( rkEvents & FD_ACCEPT )

  {

  if( SOCKET_ERROR == Code[FD_ACCEPT_BIT] )

  {

  continue;

  }

  else

  {

  //接受连接

  OnAccept();

  }

  }

  }

  }

  else if( wt == WAIT_IO_COMPLETION )

  {

  continue;

  }

  else

  {

  break;

  }

  }

  return 0;

  }

  unsigned int __stdcall CAsynch_Event_Handler::AcceptThread(void * lpParam)

  {

  CAsynch_Event_Handler *pAcceptor = (CAsynch_Event_Handler *)lpParam;

  return pAcceptor->AcceptThreadProc();

  }

  int CAsynch_Event_Handler::OnAccept()

  {

  SOCKET AcceptSocket;

  struct sockaddr_in clientAddress;

  int clientAddrLen = sizeof(sockaddr_in);

  AcceptSocket = accept( m_hListenSocket, (sockaddr *)&clientAddress, &clientAddrLen );

  if( INVALID_SOCKET == AcceptSocket )

  {

  return WSAGetLastError();

  }

  else

  {

  DWORD nValue = 1;

  int nLen = sizeof( nValue );

  if( SOCKET_ERROR == setsockopt( AcceptSocket, IPPROTO_TCP ,TCP_NODELAY, (char *)&nValue, nLen ) )

  {

  int err = WSAGetLastError();

  }

  nValue = 16384;

  if( SOCKET_ERROR == setsockopt( AcceptSocket, SOL_SOCKET ,SO_SNDBUF, (char *)&nValue, nLen ) )

  {

  int err = WSAGetLastError();

  }

  if( SOCKET_ERROR == setsockopt( AcceptSocket, SOL_SOCKET ,SO_RCVBUF, (char *)&nValue, nLen ) )

  {

  int err = WSAGetLastError();

  }

  m_pEventHandler->AcceptNotify( AcceptSocket, inet_ntoa( _addr ), ntohs( _port ) );

  return 0;

  }

  }