00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef _MSC_VER
00021 #include "stdafx.h"
00022 #else
00023 #include "config.h"
00024 #endif
00025 #include "CallStack.h"
00026
00027 #include "SocketServer.h"
00028 #include "Utility.h"
00029 #ifndef _MSC_VER
00030 #include <unistd.h>
00031 #include <sys/ioctl.h>
00032 #include <sys/types.h>
00033 #include <sys/stat.h>
00034 #endif
00035 #include <exception>
00036
00037 namespace FIX
00038 {
00040 class ServerWrapper : public SocketMonitor::Strategy
00041 {
00042 public:
00043 ServerWrapper( std::set<int> sockets, SocketServer& server,
00044 SocketServer::Strategy& strategy )
00045 : m_sockets( sockets ), m_server( server ), m_strategy( strategy ) {}
00046
00047 private:
00048 void onConnect( SocketMonitor&, int socket )
00049 { QF_STACK_PUSH(ServerWrapper::onConnect)
00050 QF_STACK_POP
00051 }
00052
00053 void onEvent( SocketMonitor&, int socket )
00054 { QF_STACK_PUSH(ServerWrapper::onEvent)
00055
00056 if( m_sockets.find(socket) != m_sockets.end() )
00057 {
00058 m_strategy.onConnect( m_server, socket, m_server.accept(socket) );
00059 }
00060 else
00061 m_strategy.onData( m_server, socket );
00062
00063 QF_STACK_POP
00064 }
00065
00066 void onWrite( SocketMonitor&, int socket )
00067 { QF_STACK_PUSH(ServerWrapper::onWrite)
00068
00069 m_strategy.onWrite( m_server, socket );
00070
00071 QF_STACK_POP
00072 }
00073
00074 void onError( SocketMonitor&, int socket )
00075 { QF_STACK_PUSH(ServerWrapper::onError)
00076
00077 m_strategy.onDisconnect( m_server, socket );
00078 m_server.getMonitor().drop( socket );
00079
00080 QF_STACK_POP
00081 }
00082
00083 void onError( SocketMonitor& )
00084 { QF_STACK_PUSH(ServerWrapper::onEvent)
00085 m_strategy.onError( m_server );
00086 QF_STACK_POP
00087 }
00088
00089 void onTimeout( SocketMonitor& )
00090 { QF_STACK_PUSH(ServerWrapper::onTimeout)
00091 m_strategy.onTimeout( m_server );
00092 QF_STACK_POP
00093 };
00094
00095 typedef std::set<int>
00096 Sockets;
00097
00098 Sockets m_sockets;
00099 SocketServer& m_server;
00100 SocketServer::Strategy& m_strategy;
00101 };
00102
00103 SocketServer::SocketServer( int timeout )
00104 : m_monitor( timeout ) {}
00105
00106 int SocketServer::add( int port, bool reuse, bool noDelay )
00107 {
00108 if( m_portToInfo.find(port) != m_portToInfo.end() )
00109 return m_portToInfo[port].m_socket;
00110
00111 int socket = socket_createAcceptor( port, reuse );
00112 if( socket < 0 )
00113 throw std::exception();
00114 if( noDelay )
00115 socket_setsockopt( socket, TCP_NODELAY );
00116 m_monitor.addRead( socket );
00117
00118 SocketInfo info( socket, port, noDelay );
00119 m_socketToInfo[socket] = info;
00120 m_portToInfo[port] = info;
00121 return socket;
00122 }
00123
00124 int SocketServer::accept( int socket )
00125 { QF_STACK_PUSH(SocketServer::accept)
00126
00127 SocketInfo info = m_socketToInfo[socket];
00128
00129 int result = socket_accept( socket );
00130 if( info.m_noDelay )
00131 socket_setsockopt( result, TCP_NODELAY );
00132 if ( result >= 0 )
00133 m_monitor.addConnect( result );
00134 return result;
00135
00136 QF_STACK_POP
00137 }
00138
00139 void SocketServer::close()
00140 { QF_STACK_PUSH(SocketServer::close)
00141
00142 SocketToInfo::iterator i = m_socketToInfo.begin();
00143 for( ; i != m_socketToInfo.end(); ++i )
00144 {
00145 int s = i->first;
00146 socket_close( s );
00147 socket_invalidate( s );
00148 }
00149
00150 QF_STACK_POP
00151 }
00152
00153 bool SocketServer::block( Strategy& strategy, bool poll )
00154 { QF_STACK_PUSH(SocketServer::block)
00155
00156 std::set<int> sockets;
00157 SocketToInfo::iterator i = m_socketToInfo.begin();
00158 for( ; i != m_socketToInfo.end(); ++i )
00159 {
00160 if( !socket_isValid(i->first) )
00161 return false;
00162 sockets.insert( i->first );
00163 }
00164
00165 ServerWrapper wrapper( sockets, *this, strategy );
00166 m_monitor.block( wrapper, poll );
00167 return true;
00168
00169 QF_STACK_POP
00170 }
00171
00172 int SocketServer::socketToPort( int socket )
00173 {
00174 SocketToInfo::iterator find = m_socketToInfo.find( socket );
00175 if( find == m_socketToInfo.end() ) return 0;
00176 return find->second.m_port;
00177 }
00178
00179 int SocketServer::portToSocket( int port )
00180 {
00181 SocketToInfo::iterator find = m_portToInfo.find( port );
00182 if( find == m_portToInfo.end() ) return 0;
00183 return find->second.m_socket;
00184 }
00185 }