SocketAcceptor.cpp
Go to the documentation of this file.
00001 /****************************************************************************
00002 ** Copyright (c) 2001-2014
00003 **
00004 ** This file is part of the QuickFIX FIX Engine
00005 **
00006 ** This file may be distributed under the terms of the quickfixengine.org
00007 ** license as defined by quickfixengine.org and appearing in the file
00008 ** LICENSE included in the packaging of this file.
00009 **
00010 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00011 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00012 **
00013 ** See http://www.quickfixengine.org/LICENSE for licensing information.
00014 **
00015 ** Contact ask@quickfixengine.org if any conditions of this licensing are
00016 ** not clear to you.
00017 **
00018 ****************************************************************************/
00019 
00020 #ifdef _MSC_VER
00021 #include "stdafx.h"
00022 #else
00023 #include "config.h"
00024 #endif
00025 
00026 #include "SocketAcceptor.h"
00027 #include "Session.h"
00028 #include "Settings.h"
00029 #include "Utility.h"
00030 #include "Exceptions.h"
00031 
00032 namespace FIX
00033 {
00034 SocketAcceptor::SocketAcceptor( Application& application,
00035                                 MessageStoreFactory& factory,
00036                                 const SessionSettings& settings ) throw( ConfigError )
00037 : Acceptor( application, factory, settings ),
00038   m_pServer( 0 ) {}
00039 
00040 SocketAcceptor::SocketAcceptor( Application& application,
00041                                 MessageStoreFactory& factory,
00042                                 const SessionSettings& settings,
00043                                 LogFactory& logFactory ) throw( ConfigError )
00044 : Acceptor( application, factory, settings, logFactory ),
00045   m_pServer( 0 ) 
00046 {
00047 }
00048 
00049 SocketAcceptor::~SocketAcceptor()
00050 {
00051   SocketConnections::iterator iter;
00052   for ( iter = m_connections.begin(); iter != m_connections.end(); ++iter )
00053     delete iter->second;
00054 }
00055 
00056 void SocketAcceptor::onConfigure( const SessionSettings& s )
00057 throw ( ConfigError )
00058 {
00059   std::set<SessionID> sessions = s.getSessions();
00060   std::set<SessionID>::iterator i;
00061   for( i = sessions.begin(); i != sessions.end(); ++i )
00062   {
00063     const Dictionary& settings = s.get( *i );
00064     settings.getInt( SOCKET_ACCEPT_PORT );
00065     if( settings.has(SOCKET_REUSE_ADDRESS) )
00066       settings.getBool( SOCKET_REUSE_ADDRESS );
00067     if( settings.has(SOCKET_NODELAY) )
00068       settings.getBool( SOCKET_NODELAY );
00069   }
00070 }
00071 
00072 void SocketAcceptor::onInitialize( const SessionSettings& s )
00073 throw ( RuntimeError )
00074 {
00075   short port = 0;
00076 
00077   try
00078   {
00079     m_pServer = new SocketServer( 1 );
00080 
00081     std::set<SessionID> sessions = s.getSessions();
00082     std::set<SessionID>::iterator i = sessions.begin();
00083     for( ; i != sessions.end(); ++i )
00084     {
00085       const Dictionary& settings = s.get( *i );
00086       port = (short)settings.getInt( SOCKET_ACCEPT_PORT );
00087 
00088       const bool reuseAddress = settings.has( SOCKET_REUSE_ADDRESS ) ? 
00089         settings.getBool( SOCKET_REUSE_ADDRESS ) : true;
00090 
00091       const bool noDelay = settings.has( SOCKET_NODELAY ) ? 
00092         settings.getBool( SOCKET_NODELAY ) : false;
00093 
00094       const int sendBufSize = settings.has( SOCKET_SEND_BUFFER_SIZE ) ?
00095         settings.getInt( SOCKET_SEND_BUFFER_SIZE ) : 0;
00096 
00097       const int rcvBufSize = settings.has( SOCKET_RECEIVE_BUFFER_SIZE ) ?
00098         settings.getInt( SOCKET_RECEIVE_BUFFER_SIZE ) : 0;
00099 
00100       m_portToSessions[port].insert( *i );
00101       m_pServer->add( port, reuseAddress, noDelay, sendBufSize, rcvBufSize );      
00102     }    
00103   }
00104   catch( SocketException& e )
00105   {
00106     throw RuntimeError( "Unable to create, bind, or listen to port "
00107                        + IntConvertor::convert( (unsigned short)port ) + " (" + e.what() + ")" );
00108   }
00109 }
00110 
00111 void SocketAcceptor::onStart()
00112 {
00113   while ( !isStopped() && m_pServer && m_pServer->block( *this ) ) {}
00114 
00115   if( !m_pServer )
00116     return;
00117 
00118   time_t start = 0;
00119   time_t now = 0;
00120 
00121   ::time( &start );
00122   while ( isLoggedOn() )
00123   {
00124     m_pServer->block( *this );
00125     if( ::time(&now) -5 >= start )
00126       break;
00127   }
00128 
00129   m_pServer->close();
00130   delete m_pServer;
00131   m_pServer = 0;
00132 }
00133 
00134 bool SocketAcceptor::onPoll( double timeout )
00135 {
00136   if( !m_pServer )
00137     return false;
00138 
00139   time_t start = 0;
00140   time_t now = 0;
00141 
00142   if( isStopped() )
00143   {
00144     if( start == 0 )
00145       ::time( &start );
00146     if( !isLoggedOn() )
00147     {
00148       start = 0;
00149       return false;
00150     }
00151     if( ::time(&now) - 5 >= start )
00152     {
00153       start = 0;
00154       return false;
00155     }
00156   }
00157 
00158   m_pServer->block( *this, true, timeout );
00159   return true;
00160 }
00161 
00162 void SocketAcceptor::onStop()
00163 {
00164 }
00165 
00166 void SocketAcceptor::onConnect( SocketServer& server, int a, int s )
00167 {
00168   if ( !socket_isValid( s ) ) return;
00169   SocketConnections::iterator i = m_connections.find( s );
00170   if ( i != m_connections.end() ) return;
00171   int port = server.socketToPort( a );
00172   Sessions sessions = m_portToSessions[port];
00173   m_connections[ s ] = new SocketConnection( s, sessions, &server.getMonitor() );
00174 
00175   std::stringstream stream;
00176   stream << "Accepted connection from " << socket_peername( s ) << " on port " << port;
00177 
00178   if( getLog() )
00179     getLog()->onEvent( stream.str() );
00180 }
00181 
00182 void SocketAcceptor::onWrite( SocketServer& server, int s )
00183 {
00184   SocketConnections::iterator i = m_connections.find( s );
00185   if ( i == m_connections.end() ) return ;
00186   SocketConnection* pSocketConnection = i->second;
00187   if( pSocketConnection->processQueue() )
00188     pSocketConnection->unsignal();
00189 }
00190 
00191 bool SocketAcceptor::onData( SocketServer& server, int s )
00192 {
00193   SocketConnections::iterator i = m_connections.find( s );
00194   if ( i == m_connections.end() ) return false;
00195   SocketConnection* pSocketConnection = i->second;
00196   return pSocketConnection->read( *this, server );
00197 }
00198 
00199 void SocketAcceptor::onDisconnect( SocketServer&, int s )
00200 {
00201   SocketConnections::iterator i = m_connections.find( s );
00202   if ( i == m_connections.end() ) return ;
00203   SocketConnection* pSocketConnection = i->second;
00204 
00205   Session* pSession = pSocketConnection->getSession();
00206   if ( pSession ) pSession->disconnect();
00207 
00208   delete pSocketConnection;
00209   m_connections.erase( s );
00210 }
00211 
00212 void SocketAcceptor::onError( SocketServer& ) 
00213 {
00214 }
00215 
00216 void SocketAcceptor::onTimeout( SocketServer& )
00217 {
00218   SocketConnections::iterator i;
00219   for ( i = m_connections.begin(); i != m_connections.end(); ++i )
00220     i->second->onTimeout();
00221 }
00222 }

Generated on Mon Jun 23 2014 23:49:38 for QuickFIX by doxygen 1.7.6.1 written by Dimitri van Heesch, © 1997-2001