157 lines
3.5 KiB
C++
157 lines
3.5 KiB
C++
|
|
|
|||
|
|
#include "StdAfx.h"
|
|||
|
|
#include "AcceptorEx.h"
|
|||
|
|
#include "ListenSocket.h"
|
|||
|
|
#include "IocpManager.h"
|
|||
|
|
#include "SocketContext.h"
|
|||
|
|
#include "SocketContextMgr.h"
|
|||
|
|
#include "Log.h"
|
|||
|
|
|
|||
|
|
#ifdef _USE_ACCEPTEX
|
|||
|
|
|
|||
|
|
CAcceptorEx::CAcceptorEx( CIocpManager* pIOCP )
|
|||
|
|
: m_pIOCP( pIOCP )
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CAcceptorEx::~CAcceptorEx()
|
|||
|
|
{
|
|||
|
|
for( UINT i=0 ; i<m_vListenSocket.size() ; ++i )
|
|||
|
|
delete m_vListenSocket[i];
|
|||
|
|
m_vListenSocket.clear();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CAcceptorEx::_bCreateSocket( const UINT uiListenID, bool bIncPoolSize )
|
|||
|
|
{
|
|||
|
|
CSocketContext* pSocketContext = CSocketContextMgr::GetInstance().pGetSocketContext();
|
|||
|
|
if( pSocketContext == NULL )
|
|||
|
|
return false;
|
|||
|
|
|
|||
|
|
pSocketContext->SetListenID( uiListenID );
|
|||
|
|
if( !pSocketContext->bInitAcceptContext() )
|
|||
|
|
return false;
|
|||
|
|
|
|||
|
|
if (bIncPoolSize) {
|
|||
|
|
ScopeLock<CSyncLock> Lock( m_Lock );
|
|||
|
|
|
|||
|
|
++m_vSocketPoolSize[uiListenID];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CAcceptorEx::_bCreateSocketPool( const UINT uiListenID, const USHORT unPort, const UINT uiPoolSize )
|
|||
|
|
{
|
|||
|
|
// SocketPool <20><><EFBFBD><EFBFBD>
|
|||
|
|
for( UINT i=0 ; i<uiPoolSize ; ++i )
|
|||
|
|
{
|
|||
|
|
if( !_bCreateSocket( uiListenID ) )
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ListenSocket IOCP <20><><EFBFBD><EFBFBD>
|
|||
|
|
if( CreateIoCompletionPort( reinterpret_cast<HANDLE>(m_vListenSocket[uiListenID]->GetSocket()), m_pIOCP->GetIocpHandle(), 0, 0 ) == 0 )
|
|||
|
|
return false;
|
|||
|
|
|
|||
|
|
g_Log.Log( LogType::_FILEDBLOG, "[%d] Listen Socket <20><><EFBFBD><EFBFBD> PORT=%d SocketPoolSize=%d\r\n", uiListenID, unPort, uiPoolSize );
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
SOCKET CAcceptorEx::GetSocket( const UINT uiListenID )
|
|||
|
|
{
|
|||
|
|
if( m_vListenSocket.size() <= uiListenID )
|
|||
|
|
return INVALID_SOCKET;
|
|||
|
|
|
|||
|
|
return m_vListenSocket[uiListenID]->GetSocket();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CAcceptorEx::GetConnectionKey( const UINT uiListenID )
|
|||
|
|
{
|
|||
|
|
if( m_vConnectionKey.size() > uiListenID )
|
|||
|
|
return m_vConnectionKey[uiListenID];
|
|||
|
|
|
|||
|
|
return CONNECTIONKEY_DEFAULT;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CAcceptorEx::bCreateListenSocket( const USHORT unPort, const UINT uiPoolSize, const int iKey )
|
|||
|
|
{
|
|||
|
|
CListenSocket* pListenSocket = new (std::nothrow) CListenSocket();
|
|||
|
|
if( pListenSocket == NULL )
|
|||
|
|
{
|
|||
|
|
g_Log.Log( LogType::_FILELOG, "CListenSocket <20><>ü <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>\r\n" );
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ListenSocket <20>ʱ<EFBFBD>ȭ
|
|||
|
|
if( !pListenSocket->bInitialize( unPort ) )
|
|||
|
|
{
|
|||
|
|
delete pListenSocket;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ListenSocket <20><><EFBFBD><EFBFBD>
|
|||
|
|
UINT uiListenID = static_cast<UINT>(m_vListenSocket.size());
|
|||
|
|
m_vListenSocket.push_back( pListenSocket );
|
|||
|
|
|
|||
|
|
// SocketPool <20><><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ
|
|||
|
|
m_vSocketPoolSize.push_back( 0 );
|
|||
|
|
m_vUsedSocketSize.push_back( 0 );
|
|||
|
|
m_vConnectionKey.push_back( iKey );
|
|||
|
|
|
|||
|
|
return _bCreateSocketPool( uiListenID, unPort, uiPoolSize );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CAcceptorEx::bOnAccept( const UINT uiListenID )
|
|||
|
|
{
|
|||
|
|
bool bDoCreate = false;
|
|||
|
|
{
|
|||
|
|
ScopeLock<CSyncLock> Lock( m_Lock );
|
|||
|
|
|
|||
|
|
++m_vUsedSocketSize[uiListenID];
|
|||
|
|
|
|||
|
|
// SocketPoolSize <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Socket <20><> 50% <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
|||
|
|
if( m_vUsedSocketSize[uiListenID] >= static_cast<UINT>(m_vSocketPoolSize[uiListenID]*0.5f) ) {
|
|||
|
|
++m_vSocketPoolSize[uiListenID];
|
|||
|
|
|
|||
|
|
bDoCreate = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (bDoCreate) {
|
|||
|
|
if( !_bCreateSocket( uiListenID, false ) ) {
|
|||
|
|
ScopeLock<CSyncLock> Lock( m_Lock );
|
|||
|
|
|
|||
|
|
--m_vSocketPoolSize[uiListenID];
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
g_Log.Log( LogType::_FILEDBLOG, "[ListenID=%d] SocketPool <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> Socket <20><><EFBFBD><EFBFBD>\r\n", uiListenID );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CAcceptorEx::bOnClose( CSocketContext* pSocketContext )
|
|||
|
|
{
|
|||
|
|
ScopeLock<CSyncLock> Lock( m_Lock );
|
|||
|
|
|
|||
|
|
if( !pSocketContext->bInitAcceptContext() )
|
|||
|
|
return false;
|
|||
|
|
|
|||
|
|
UINT uiListenID = pSocketContext->uiGetListenID();
|
|||
|
|
|
|||
|
|
if( m_vUsedSocketSize[uiListenID] )
|
|||
|
|
--m_vUsedSocketSize[uiListenID];
|
|||
|
|
else
|
|||
|
|
return false;
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endif // #ifdef _USE_ACCEPTEX
|
|||
|
|
|
|||
|
|
|
|||
|
|
|