#include
#include
#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
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;
}
}
#include
#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
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;
}
}