SocketAcceptor.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 ** Copyright (c) 2001-2014
3 **
4 ** This file is part of the QuickFIX FIX Engine
5 **
6 ** This file may be distributed under the terms of the quickfixengine.org
7 ** license as defined by quickfixengine.org and appearing in the file
8 ** LICENSE included in the packaging of this file.
9 **
10 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
11 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
12 **
13 ** See http://www.quickfixengine.org/LICENSE for licensing information.
14 **
15 ** Contact ask@quickfixengine.org if any conditions of this licensing are
16 ** not clear to you.
17 **
18 ****************************************************************************/
19 
20 #ifdef _MSC_VER
21 #include "stdafx.h"
22 #else
23 #include "config.h"
24 #endif
25 
26 #include "SocketAcceptor.h"
27 #include "Session.h"
28 #include "Settings.h"
29 #include "Utility.h"
30 #include "Exceptions.h"
31 
32 namespace FIX
33 {
34 SocketAcceptor::SocketAcceptor( Application& application,
35  MessageStoreFactory& factory,
36  const SessionSettings& settings ) throw( ConfigError )
37 : Acceptor( application, factory, settings ),
38  m_pServer( 0 ) {}
39 
40 SocketAcceptor::SocketAcceptor( Application& application,
41  MessageStoreFactory& factory,
42  const SessionSettings& settings,
43  LogFactory& logFactory ) throw( ConfigError )
44 : Acceptor( application, factory, settings, logFactory ),
45  m_pServer( 0 )
46 {
47 }
48 
50 {
51  SocketConnections::iterator iter;
52  for ( iter = m_connections.begin(); iter != m_connections.end(); ++iter )
53  delete iter->second;
54 }
55 
57 throw ( ConfigError )
58 {
59  std::set<SessionID> sessions = s.getSessions();
60  std::set<SessionID>::iterator i;
61  for( i = sessions.begin(); i != sessions.end(); ++i )
62  {
63  const Dictionary& settings = s.get( *i );
64  settings.getInt( SOCKET_ACCEPT_PORT );
65  if( settings.has(SOCKET_REUSE_ADDRESS) )
67  if( settings.has(SOCKET_NODELAY) )
68  settings.getBool( SOCKET_NODELAY );
69  }
70 }
71 
72 void SocketAcceptor::onInitialize( const SessionSettings& s )
73 throw ( RuntimeError )
74 {
75  short port = 0;
76 
77  try
78  {
79  m_pServer = new SocketServer( 1 );
80 
81  std::set<SessionID> sessions = s.getSessions();
82  std::set<SessionID>::iterator i = sessions.begin();
83  for( ; i != sessions.end(); ++i )
84  {
85  const Dictionary& settings = s.get( *i );
86  port = (short)settings.getInt( SOCKET_ACCEPT_PORT );
87 
88  const bool reuseAddress = settings.has( SOCKET_REUSE_ADDRESS ) ?
89  settings.getBool( SOCKET_REUSE_ADDRESS ) : true;
90 
91  const bool noDelay = settings.has( SOCKET_NODELAY ) ?
92  settings.getBool( SOCKET_NODELAY ) : false;
93 
94  const int sendBufSize = settings.has( SOCKET_SEND_BUFFER_SIZE ) ?
95  settings.getInt( SOCKET_SEND_BUFFER_SIZE ) : 0;
96 
97  const int rcvBufSize = settings.has( SOCKET_RECEIVE_BUFFER_SIZE ) ?
98  settings.getInt( SOCKET_RECEIVE_BUFFER_SIZE ) : 0;
99 
100  m_portToSessions[port].insert( *i );
101  m_pServer->add( port, reuseAddress, noDelay, sendBufSize, rcvBufSize );
102  }
103  }
104  catch( SocketException& e )
105  {
106  throw RuntimeError( "Unable to create, bind, or listen to port "
107  + IntConvertor::convert( (unsigned short)port ) + " (" + e.what() + ")" );
108  }
109 }
110 
112 {
113  while ( !isStopped() && m_pServer && m_pServer->block( *this ) ) {}
114 
115  if( !m_pServer )
116  return;
117 
118  time_t start = 0;
119  time_t now = 0;
120 
121  ::time( &start );
122  while ( isLoggedOn() )
123  {
124  m_pServer->block( *this );
125  if( ::time(&now) -5 >= start )
126  break;
127  }
128 
129  m_pServer->close();
130  delete m_pServer;
131  m_pServer = 0;
132 }
133 
134 bool SocketAcceptor::onPoll( double timeout )
135 {
136  if( !m_pServer )
137  return false;
138 
139  time_t start = 0;
140  time_t now = 0;
141 
142  if( isStopped() )
143  {
144  if( start == 0 )
145  ::time( &start );
146  if( !isLoggedOn() )
147  {
148  start = 0;
149  return false;
150  }
151  if( ::time(&now) - 5 >= start )
152  {
153  start = 0;
154  return false;
155  }
156  }
157 
158  m_pServer->block( *this, true, timeout );
159  return true;
160 }
161 
163 {
164 }
165 
166 void SocketAcceptor::onConnect( SocketServer& server, int a, int s )
167 {
168  if ( !socket_isValid( s ) ) return;
169  SocketConnections::iterator i = m_connections.find( s );
170  if ( i != m_connections.end() ) return;
171  int port = server.socketToPort( a );
172  Sessions sessions = m_portToSessions[port];
173  m_connections[ s ] = new SocketConnection( s, sessions, &server.getMonitor() );
174 
175  std::stringstream stream;
176  stream << "Accepted connection from " << socket_peername( s ) << " on port " << port;
177 
178  if( getLog() )
179  getLog()->onEvent( stream.str() );
180 }
181 
182 void SocketAcceptor::onWrite( SocketServer& server, int s )
183 {
184  SocketConnections::iterator i = m_connections.find( s );
185  if ( i == m_connections.end() ) return ;
186  SocketConnection* pSocketConnection = i->second;
187  if( pSocketConnection->processQueue() )
188  pSocketConnection->unsignal();
189 }
190 
191 bool SocketAcceptor::onData( SocketServer& server, int s )
192 {
193  SocketConnections::iterator i = m_connections.find( s );
194  if ( i == m_connections.end() ) return false;
195  SocketConnection* pSocketConnection = i->second;
196  return pSocketConnection->read( *this, server );
197 }
198 
200 {
201  SocketConnections::iterator i = m_connections.find( s );
202  if ( i == m_connections.end() ) return ;
203  SocketConnection* pSocketConnection = i->second;
204 
205  Session* pSession = pSocketConnection->getSession();
206  if ( pSession ) pSession->disconnect();
207 
208  delete pSocketConnection;
209  m_connections.erase( s );
210 }
211 
213 {
214 }
215 
217 {
218  SocketConnections::iterator i;
219  for ( i = m_connections.begin(); i != m_connections.end(); ++i )
220  i->second->onTimeout();
221 }
222 }
FIX::SOCKET_RECEIVE_BUFFER_SIZE
const char SOCKET_RECEIVE_BUFFER_SIZE[]
Definition: SessionSettings.h:87
FIX::Acceptor::getLog
Log * getLog()
Definition: Acceptor.h:76
FIX::SocketConnection::unsignal
void unsignal()
Definition: SocketConnection.h:86
FIX::SOCKET_NODELAY
const char SOCKET_NODELAY[]
Definition: SessionSettings.h:85
FIX::SocketAcceptor::SocketConnection
friend class SocketConnection
Definition: SocketAcceptor.h:72
FIX::Dictionary::getInt
int getInt(const std::string &) const
Get a value as a int.
Definition: Dictionary.cpp:62
FIX::SocketAcceptor::onConnect
void onConnect(SocketServer &, int, int)
Definition: SocketAcceptor.cpp:183
FIX::SocketServer::block
bool block(Strategy &strategy, bool poll=0, double timeout=0.0)
Definition: SocketServer.cpp:165
FIX::Acceptor::start
void start()
Start acceptor.
Definition: Acceptor.cpp:175
FIX::SocketAcceptor::SocketAcceptor
SocketAcceptor(Application &, MessageStoreFactory &, const SessionSettings &)
Definition: SocketAcceptor.cpp:51
FIX::SOCKET_SEND_BUFFER_SIZE
const char SOCKET_SEND_BUFFER_SIZE[]
Definition: SessionSettings.h:86
FIX::ConfigError
Application is not configured correctly
Definition: Exceptions.h:104
FIX::SocketAcceptor::onPoll
bool onPoll(double timeout)
Implemented to connect and poll for events.
Definition: SocketAcceptor.cpp:151
FIX::SocketAcceptor::onInitialize
void onInitialize(const SessionSettings &)
Implemented to initialize acceptor.
Definition: SocketAcceptor.cpp:89
FIX::RuntimeError
Application encountered serious error during runtime
Definition: Exceptions.h:111
FIX::SocketServer::close
void close()
Definition: SocketServer.cpp:154
FIX::socket_isValid
bool socket_isValid(int socket)
Definition: Utility.cpp:294
FIX::SOCKET_ACCEPT_PORT
const char SOCKET_ACCEPT_PORT[]
Definition: SessionSettings.h:79
FIX::SocketAcceptor::onWrite
void onWrite(SocketServer &, int)
Definition: SocketAcceptor.cpp:199
FIX::SessionSettings
Container for setting dictionaries mapped to sessions.
Definition: SessionSettings.h:237
FIX::SocketAcceptor::onStop
void onStop()
Implemented to stop a running acceptor.
Definition: SocketAcceptor.cpp:179
FIX::SocketAcceptor::m_pServer
SocketServer * m_pServer
Definition: SocketAcceptor.h:102
FIX::IntConvertor::convert
static std::string convert(signed_int value)
Definition: FieldConvertors.h:170
FIX::Acceptor::isLoggedOn
bool isLoggedOn()
Check to see if any sessions are currently logged on.
Definition: Acceptor.cpp:247
FIX::Log::onEvent
virtual void onEvent(const std::string &)=0
FIX::SessionSettings::getSessions
std::set< SessionID > getSessions() const
Definition: SessionSettings.cpp:177
FIX::Dictionary::has
bool has(const std::string &) const
Check if the dictionary contains a value for key.
Definition: Dictionary.cpp:166
FIX::SocketAcceptor::onDisconnect
void onDisconnect(SocketServer &, int)
Definition: SocketAcceptor.cpp:216
FIX::SocketAcceptor::onTimeout
void onTimeout(SocketServer &)
Definition: SocketAcceptor.cpp:233
FIX::SocketConnection::getSession
Session * getSession() const
Definition: SocketConnection.h:73
FIX::SocketAcceptor::onError
void onError(SocketServer &)
Definition: SocketAcceptor.cpp:229
FIX::SocketAcceptor::m_connections
SocketConnections m_connections
Definition: SocketAcceptor.h:104
Settings.h
FIX::Dictionary::getBool
bool getBool(const std::string &) const
Get a value as a bool.
Definition: Dictionary.cpp:88
FIX::SocketAcceptor::onConfigure
void onConfigure(const SessionSettings &)
Implemented to configure acceptor.
Definition: SocketAcceptor.cpp:73
FIX
Definition: Acceptor.cpp:34
FIX::SocketConnection::processQueue
bool processQueue()
Definition: SocketConnection.cpp:89
FIX::SocketAcceptor::Sessions
std::set< SessionID > Sessions
Definition: SocketAcceptor.h:84
FIX::Session::disconnect
void disconnect()
Definition: Session.cpp:630
Session.h
FIX::SocketConnection::read
bool read(SocketConnector &s)
Definition: SocketConnection.cpp:123
FIX::SocketAcceptor::m_portToSessions
PortToSessions m_portToSessions
Definition: SocketAcceptor.h:103
Exceptions.h
FIX::SocketAcceptor::~SocketAcceptor
virtual ~SocketAcceptor()
Definition: SocketAcceptor.cpp:66
SocketAcceptor.h
FIX::SocketServer
Listens for and accepts incoming socket connections on a port.
Definition: SocketServer.h:73
FIX::SocketAcceptor::onData
bool onData(SocketServer &, int)
Definition: SocketAcceptor.cpp:208
Utility.h
FIX::Acceptor::isStopped
bool isStopped()
Definition: Acceptor.h:104
FIX::SessionSettings::get
const Dictionary & get(const SessionID &) const
Get a dictionary for a session.
Definition: SessionSettings.cpp:144
FIX::SOCKET_REUSE_ADDRESS
const char SOCKET_REUSE_ADDRESS[]
Definition: SessionSettings.h:80
FIX::Dictionary
For storage and retrieval of key/value pairs.
Definition: Dictionary.h:53
FIX::SocketConnection
Encapsulates a socket file descriptor (single-threaded).
Definition: SocketConnection.h:63
FIX::SocketAcceptor::onStart
void onStart()
Implemented to start listening for connections.
Definition: SocketAcceptor.cpp:128
FIX::socket_peername
const char * socket_peername(int socket)
Definition: Utility.cpp:370
FIX::Session
Maintains the state and implements the logic of a FIX session.
Definition: Session.h:62

Generated on Wed Apr 29 2020 19:41:30 for QuickFIX by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2001