SocketAcceptor.cpp
Go to the documentation of this file.
/****************************************************************************
** Copyright (c) 2001-2014
**
** This file is part of the QuickFIX FIX Engine
**
** This file may be distributed under the terms of the quickfixengine.org
** license as defined by quickfixengine.org and appearing in the file
** LICENSE included in the packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.quickfixengine.org/LICENSE for licensing information.
**
** Contact ask@quickfixengine.org if any conditions of this licensing are
** not clear to you.
**
****************************************************************************/
#ifdef _MSC_VER
#include "stdafx.h"
#else
#include "config.h"
#endif
#include "SocketAcceptor.h"
#include "Session.h"
#include "Settings.h"
#include "Utility.h"
#include "Exceptions.h"
namespace FIX
{
SocketAcceptor::SocketAcceptor( Application& application,
MessageStoreFactory& factory,
const SessionSettings& settings ) throw( ConfigError )
: Acceptor( application, factory, settings ),
m_pServer( 0 ) {}
SocketAcceptor::SocketAcceptor( Application& application,
MessageStoreFactory& factory,
const SessionSettings& settings,
LogFactory& logFactory ) throw( ConfigError )
: Acceptor( application, factory, settings, logFactory ),
m_pServer( 0 )
{
}
SocketAcceptor::~SocketAcceptor()
{
SocketConnections::iterator iter;
for ( iter = m_connections.begin(); iter != m_connections.end(); ++iter )
delete iter->second;
}
void SocketAcceptor::onConfigure( const SessionSettings& s )
throw ( ConfigError )
{
std::set<SessionID> sessions = s.getSessions();
std::set<SessionID>::iterator i;
for( i = sessions.begin(); i != sessions.end(); ++i )
{
const Dictionary& settings = s.get( *i );
settings.getInt( SOCKET_ACCEPT_PORT );
if( settings.has(SOCKET_REUSE_ADDRESS) )
settings.getBool( SOCKET_REUSE_ADDRESS );
if( settings.has(SOCKET_NODELAY) )
settings.getBool( SOCKET_NODELAY );
}
}
void SocketAcceptor::onInitialize( const SessionSettings& s )
throw ( RuntimeError )
{
short port = 0;
try
{
m_pServer = new SocketServer( 1 );
std::set<SessionID> sessions = s.getSessions();
std::set<SessionID>::iterator i = sessions.begin();
for( ; i != sessions.end(); ++i )
{
const Dictionary& settings = s.get( *i );
port = (short)settings.getInt( SOCKET_ACCEPT_PORT );
const bool reuseAddress = settings.has( SOCKET_REUSE_ADDRESS ) ?
settings.getBool( SOCKET_REUSE_ADDRESS ) : true;
const bool noDelay = settings.has( SOCKET_NODELAY ) ?
settings.getBool( SOCKET_NODELAY ) : false;
const int sendBufSize = settings.has( SOCKET_SEND_BUFFER_SIZE ) ?
settings.getInt( SOCKET_SEND_BUFFER_SIZE ) : 0;
const int rcvBufSize = settings.has( SOCKET_RECEIVE_BUFFER_SIZE ) ?
settings.getInt( SOCKET_RECEIVE_BUFFER_SIZE ) : 0;
m_portToSessions[port].insert( *i );
m_pServer->add( port, reuseAddress, noDelay, sendBufSize, rcvBufSize );
}
}
catch( SocketException& e )
{
throw RuntimeError( "Unable to create, bind, or listen to port "
+ IntConvertor::convert( (unsigned short)port ) + " (" + e.what() + ")" );
}
}
void SocketAcceptor::onStart()
{
while ( !isStopped() && m_pServer && m_pServer->block( *this ) ) {}
if( !m_pServer )
return;
time_t start = 0;
time_t now = 0;
::time( &start );
while ( isLoggedOn() )
{
m_pServer->block( *this );
if( ::time(&now) -5 >= start )
break;
}
m_pServer->close();
delete m_pServer;
m_pServer = 0;
}
bool SocketAcceptor::onPoll( double timeout )
{
if( !m_pServer )
return false;
time_t start = 0;
time_t now = 0;
if( isStopped() )
{
if( start == 0 )
::time( &start );
if( !isLoggedOn() )
{
start = 0;
return false;
}
if( ::time(&now) - 5 >= start )
{
start = 0;
return false;
}
}
m_pServer->block( *this, true, timeout );
return true;
}
void SocketAcceptor::onStop()
{
}
void SocketAcceptor::onConnect( SocketServer& server, int a, int s )
{
if ( !socket_isValid( s ) ) return;
SocketConnections::iterator i = m_connections.find( s );
if ( i != m_connections.end() ) return;
int port = server.socketToPort( a );
Sessions sessions = m_portToSessions[port];
m_connections[ s ] = new SocketConnection( s, sessions, &server.getMonitor() );
std::stringstream stream;
stream << "Accepted connection from " << socket_peername( s ) << " on port " << port;
if( getLog() )
getLog()->onEvent( stream.str() );
}
void SocketAcceptor::onWrite( SocketServer& server, int s )
{
SocketConnections::iterator i = m_connections.find( s );
if ( i == m_connections.end() ) return ;
SocketConnection* pSocketConnection = i->second;
if( pSocketConnection->processQueue() )
pSocketConnection->unsignal();
}
bool SocketAcceptor::onData( SocketServer& server, int s )
{
SocketConnections::iterator i = m_connections.find( s );
if ( i == m_connections.end() ) return false;
SocketConnection* pSocketConnection = i->second;
return pSocketConnection->read( *this, server );
}
void SocketAcceptor::onDisconnect( SocketServer&, int s )
{
SocketConnections::iterator i = m_connections.find( s );
if ( i == m_connections.end() ) return ;
SocketConnection* pSocketConnection = i->second;
Session* pSession = pSocketConnection->getSession();
if ( pSession ) pSession->disconnect();
delete pSocketConnection;
m_connections.erase( s );
}
void SocketAcceptor::onError( SocketServer& )
{
}
void SocketAcceptor::onTimeout( SocketServer& )
{
SocketConnections::iterator i;
for ( i = m_connections.begin(); i != m_connections.end(); ++i )
i->second->onTimeout();
}
}
Exceptions.h
Session.h
Settings.h
SocketAcceptor.h
Utility.h
FIX::Acceptor
Base for classes which act as an acceptor for incoming connections.
Definition: Acceptor.h:50
FIX::Acceptor::start
void start()
Start acceptor.
Definition: Acceptor.cpp:158
FIX::Acceptor::getLog
Log * getLog()
Definition: Acceptor.h:59
FIX::Acceptor::Sessions
std::map< SessionID, Session * > Sessions
Definition: Acceptor.h:110
FIX::Acceptor::isStopped
bool isStopped()
Definition: Acceptor.h:87
FIX::Acceptor::isLoggedOn
bool isLoggedOn()
Check to see if any sessions are currently logged on.
Definition: Acceptor.cpp:230
FIX::Application
This interface must be implemented to define what your FIX application does.
Definition: Application.h:44
FIX::Dictionary
For storage and retrieval of key/value pairs.
Definition: Dictionary.h:37
FIX::Dictionary::getInt
int getInt(const std::string &) const
Get a value as a int.
Definition: Dictionary.cpp:45
FIX::Dictionary::getBool
bool getBool(const std::string &) const
Get a value as a bool.
Definition: Dictionary.cpp:71
FIX::Dictionary::has
bool has(const std::string &) const
Check if the dictionary contains a value for key.
Definition: Dictionary.cpp:149
FIX::LogFactory
This interface must be implemented to create a Log.
Definition: Log.h:43
FIX::Log::onEvent
virtual void onEvent(const std::string &)=0
FIX::MessageStoreFactory
This interface must be implemented to create a MessageStore.
Definition: MessageStore.h:42
FIX::Session
Maintains the state and implements the logic of a FIX session.
Definition: Session.h:46
FIX::Session::disconnect
void disconnect()
Definition: Session.cpp:613
FIX::SessionSettings
Container for setting dictionaries mapped to sessions.
Definition: SessionSettings.h:221
FIX::SocketAcceptor::onConfigure
void onConfigure(const SessionSettings &)
Implemented to configure acceptor.
Definition: SocketAcceptor.cpp:56
FIX::SocketAcceptor::SocketConnection
friend class SocketConnection
Definition: SocketAcceptor.h:38
FIX::SocketAcceptor::m_portToSessions
PortToSessions m_portToSessions
Definition: SocketAcceptor.h:69
FIX::SocketAcceptor::onWrite
void onWrite(SocketServer &, int)
Definition: SocketAcceptor.cpp:182
FIX::SocketAcceptor::m_pServer
SocketServer * m_pServer
Definition: SocketAcceptor.h:68
FIX::SocketAcceptor::onStart
void onStart()
Implemented to start listening for connections.
Definition: SocketAcceptor.cpp:111
FIX::SocketAcceptor::onError
void onError(SocketServer &)
Definition: SocketAcceptor.cpp:212
FIX::SocketAcceptor::SocketAcceptor
SocketAcceptor(Application &, MessageStoreFactory &, const SessionSettings &)
Definition: SocketAcceptor.cpp:34
FIX::SocketAcceptor::onConnect
void onConnect(SocketServer &, int, int)
Definition: SocketAcceptor.cpp:166
FIX::SocketAcceptor::onTimeout
void onTimeout(SocketServer &)
Definition: SocketAcceptor.cpp:216
FIX::SocketAcceptor::onStop
void onStop()
Implemented to stop a running acceptor.
Definition: SocketAcceptor.cpp:162
FIX::SocketAcceptor::~SocketAcceptor
virtual ~SocketAcceptor()
Definition: SocketAcceptor.cpp:49
FIX::SocketAcceptor::onInitialize
void onInitialize(const SessionSettings &)
Implemented to initialize acceptor.
Definition: SocketAcceptor.cpp:72
FIX::SocketAcceptor::onPoll
bool onPoll(double timeout)
Implemented to connect and poll for events.
Definition: SocketAcceptor.cpp:134
FIX::SocketAcceptor::onDisconnect
void onDisconnect(SocketServer &, int)
Definition: SocketAcceptor.cpp:199
FIX::SocketAcceptor::m_connections
SocketConnections m_connections
Definition: SocketAcceptor.h:70
FIX::SocketAcceptor::onData
bool onData(SocketServer &, int)
Definition: SocketAcceptor.cpp:191
FIX::SocketConnection
Encapsulates a socket file descriptor (single-threaded).
Definition: SocketConnection.h:47
FIX::SocketConnection::getSession
Session * getSession() const
Definition: SocketConnection.h:56
FIX::SocketConnection::unsignal
void unsignal()
Definition: SocketConnection.h:69
FIX::SocketConnection::processQueue
bool processQueue()
Definition: SocketConnection.cpp:72
FIX::SocketConnection::read
bool read(SocketConnector &s)
Definition: SocketConnection.cpp:106
FIX::SocketServer
Listens for and accepts incoming socket connections on a port.
Definition: SocketServer.h:57
FIX::SocketServer::block
bool block(Strategy &strategy, bool poll=0, double timeout=0.0)
Definition: SocketServer.cpp:148
FIX::SocketServer::socketToPort
int socketToPort(int socket)
Definition: SocketServer.cpp:164
FIX::SocketServer::getMonitor
SocketMonitor & getMonitor()
Definition: SocketServer.h:70
FIX::SocketServer::close
void close()
Definition: SocketServer.cpp:137
FIX
Definition: Acceptor.cpp:35
FIX::SOCKET_SEND_BUFFER_SIZE
const char SOCKET_SEND_BUFFER_SIZE[]
Definition: SessionSettings.h:69
FIX::SOCKET_ACCEPT_PORT
const char SOCKET_ACCEPT_PORT[]
Definition: SessionSettings.h:62
FIX::SOCKET_REUSE_ADDRESS
const char SOCKET_REUSE_ADDRESS[]
Definition: SessionSettings.h:63
FIX::SOCKET_NODELAY
const char SOCKET_NODELAY[]
Definition: SessionSettings.h:68
FIX::SOCKET_RECEIVE_BUFFER_SIZE
const char SOCKET_RECEIVE_BUFFER_SIZE[]
Definition: SessionSettings.h:70
FIX::socket_isValid
bool socket_isValid(int socket)
Definition: Utility.cpp:277
FIX::socket_peername
const char * socket_peername(int socket)
Definition: Utility.cpp:353
FIX::ConfigError
Application is not configured correctly
Definition: Exceptions.h:88
FIX::IntConvertor::convert
static std::string convert(signed_int value)
Definition: FieldConvertors.h:153
FIX::RuntimeError
Application encountered serious error during runtime
Definition: Exceptions.h:95
FIX::SocketException
Socket Error.
Definition: Exceptions.h:246