读书人

C++应用实例十四

发布时间: 2008-12-20 19:29:15 作者: liuhuituzi

#include <winsock2.h>
  #include <process.h>
  #pragma comment(lib,"ws2_32.lib")
  #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( wsaData.wVersion ) != 2 ||
  HIBYTE( wsaData.wVersion ) != 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 <iostream>
  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));
  serverAddress.sin_family = AF_INET;
  serverAddress.sin_addr.s_addr = 0;
  serverAddress.sin_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( Events.lNetworkEvents & FD_ACCEPT )
  {
  if( SOCKET_ERROR == Events.iErrorCode[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( clientAddress.sin_addr ), ntohs( clientAddress.sin_port ) );
  return 0;
  }
  }

3COME考试频道为您精心整理,希望对您有所帮助,更多信息在http://www.reader8.net/exam/

读书人网 >复习指导

热点推荐