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
32namespace FIX
33{
35 MessageStoreFactory& factory,
36 const SessionSettings& settings ) throw( ConfigError )
37: Acceptor( application, factory, settings ),
38 m_pServer( 0 ) {}
39
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
57throw ( 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) )
66 settings.getBool( SOCKET_REUSE_ADDRESS );
67 if( settings.has(SOCKET_NODELAY) )
68 settings.getBool( SOCKET_NODELAY );
69 }
70}
71
73throw ( 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
134bool 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
166void 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
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
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
215
217{
218 SocketConnections::iterator i;
219 for ( i = m_connections.begin(); i != m_connections.end(); ++i )
220 i->second->onTimeout();
221}
222}
Base for classes which act as an acceptor for incoming connections.
Definition Acceptor.h:50
void start()
Start acceptor.
Definition Acceptor.cpp:158
bool isStopped()
Definition Acceptor.h:87
bool isLoggedOn()
Check to see if any sessions are currently logged on.
Definition Acceptor.cpp:230
Log * getLog()
Definition Acceptor.h:59
This interface must be implemented to define what your FIX application does.
Definition Application.h:44
For storage and retrieval of key/value pairs.
Definition Dictionary.h:37
int getInt(const std::string &) const
Get a value as a int.
bool getBool(const std::string &) const
Get a value as a bool.
bool has(const std::string &) const
Check if the dictionary contains a value for key.
This interface must be implemented to create a Log.
Definition Log.h:43
virtual void onEvent(const std::string &)=0
This interface must be implemented to create a MessageStore.
Maintains the state and implements the logic of a FIX session.
Definition Session.h:46
void disconnect()
Definition Session.cpp:613
Container for setting dictionaries mapped to sessions.
void onConfigure(const SessionSettings &)
Implemented to configure acceptor.
friend class SocketConnection
std::set< SessionID > Sessions
PortToSessions m_portToSessions
void onWrite(SocketServer &, int)
SocketServer * m_pServer
void onStart()
Implemented to start listening for connections.
void onError(SocketServer &)
SocketAcceptor(Application &, MessageStoreFactory &, const SessionSettings &)
void onConnect(SocketServer &, int, int)
void onTimeout(SocketServer &)
void onStop()
Implemented to stop a running acceptor.
void onInitialize(const SessionSettings &)
Implemented to initialize acceptor.
bool onPoll(double timeout)
Implemented to connect and poll for events.
void onDisconnect(SocketServer &, int)
SocketConnections m_connections
bool onData(SocketServer &, int)
Encapsulates a socket file descriptor (single-threaded).
Session * getSession() const
bool read(SocketConnector &s)
Listens for and accepts incoming socket connections on a port.
bool block(Strategy &strategy, bool poll=0, double timeout=0.0)
int socketToPort(int socket)
SocketMonitor & getMonitor()
const char SOCKET_SEND_BUFFER_SIZE[]
const char SOCKET_ACCEPT_PORT[]
const char SOCKET_REUSE_ADDRESS[]
const char SOCKET_NODELAY[]
const char SOCKET_RECEIVE_BUFFER_SIZE[]
bool socket_isValid(int socket)
Definition Utility.cpp:277
const char * socket_peername(int socket)
Definition Utility.cpp:353
Application is not configured correctly
Definition Exceptions.h:88
static std::string convert(signed_int value)
Application encountered serious error during runtime
Definition Exceptions.h:95
Socket Error.
Definition Exceptions.h:246

Generated on Sun Mar 31 2024 07:07:24 for QuickFIX by doxygen 1.9.8 written by Dimitri van Heesch, © 1997-2001