SocketServer.cpp
Go to the documentation of this file.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 #include "Exceptions.h"
00030 #ifndef _MSC_VER
00031 #include <unistd.h>
00032 #include <sys/ioctl.h>
00033 #include <sys/types.h>
00034 #include <sys/stat.h>
00035 #endif
00036 #include <exception>
00037
00038 namespace FIX
00039 {
00041 class ServerWrapper : public SocketMonitor::Strategy
00042 {
00043 public:
00044 ServerWrapper( std::set<int> sockets, SocketServer& server,
00045 SocketServer::Strategy& strategy )
00046 : m_sockets( sockets ), m_server( server ), m_strategy( strategy ) {}
00047
00048 private:
00049 void onConnect( SocketMonitor&, int socket )
00050 { QF_STACK_PUSH(ServerWrapper::onConnect)
00051 QF_STACK_POP
00052 }
00053
00054 void onEvent( SocketMonitor& monitor, int socket )
00055 { QF_STACK_PUSH(ServerWrapper::onEvent)
00056
00057 if( m_sockets.find(socket) != m_sockets.end() )
00058 {
00059 m_strategy.onConnect( m_server, socket, m_server.accept(socket) );
00060 }
00061 else
00062 {
00063 if( !m_strategy.onData( m_server, socket ) )
00064 onError( monitor, socket );
00065 }
00066
00067 QF_STACK_POP
00068 }
00069
00070 void onWrite( SocketMonitor&, int socket )
00071 { QF_STACK_PUSH(ServerWrapper::onWrite)
00072
00073 m_strategy.onWrite( m_server, socket );
00074
00075 QF_STACK_POP
00076 }
00077
00078 void onError( SocketMonitor& monitor, int socket )
00079 { QF_STACK_PUSH(ServerWrapper::onError)
00080
00081 m_strategy.onDisconnect( m_server, socket );
00082 monitor.drop( socket );
00083
00084 QF_STACK_POP
00085 }
00086
00087 void onError( SocketMonitor& )
00088 { QF_STACK_PUSH(ServerWrapper::onError)
00089 m_strategy.onError( m_server );
00090 QF_STACK_POP
00091 }
00092
00093 void onTimeout( SocketMonitor& )
00094 { QF_STACK_PUSH(ServerWrapper::onTimeout)
00095 m_strategy.onTimeout( m_server );
00096 QF_STACK_POP
00097 };
00098
00099 typedef std::set<int>
00100 Sockets;
00101
00102 Sockets m_sockets;
00103 SocketServer& m_server;
00104 SocketServer::Strategy& m_strategy;
00105 };
00106
00107 SocketServer::SocketServer( int timeout )
00108 : m_monitor( timeout ) {}
00109
00110 int SocketServer::add( int port, bool reuse, bool noDelay,
00111 int sendBufSize, int rcvBufSize )
00112 throw( SocketException& )
00113 {
00114 if( m_portToInfo.find(port) != m_portToInfo.end() )
00115 return m_portToInfo[port].m_socket;
00116
00117 int socket = socket_createAcceptor( port, reuse );
00118 if( socket < 0 )
00119 throw SocketException();
00120 if( noDelay )
00121 socket_setsockopt( socket, TCP_NODELAY );
00122 if( sendBufSize )
00123 socket_setsockopt( socket, SO_SNDBUF, sendBufSize );
00124 if( rcvBufSize )
00125 socket_setsockopt( socket, SO_RCVBUF, rcvBufSize );
00126 m_monitor.addRead( socket );
00127
00128 SocketInfo info( socket, port, noDelay, sendBufSize, rcvBufSize );
00129 m_socketToInfo[socket] = info;
00130 m_portToInfo[port] = info;
00131 return socket;
00132 }
00133
00134 int SocketServer::accept( int socket )
00135 { QF_STACK_PUSH(SocketServer::accept)
00136
00137 SocketInfo info = m_socketToInfo[socket];
00138
00139 int result = socket_accept( socket );
00140 if( info.m_noDelay )
00141 socket_setsockopt( result, TCP_NODELAY );
00142 if( info.m_sendBufSize )
00143 socket_setsockopt( result, SO_SNDBUF, info.m_sendBufSize );
00144 if( info.m_rcvBufSize )
00145 socket_setsockopt( result, SO_RCVBUF, info.m_rcvBufSize );
00146 if ( result >= 0 )
00147 m_monitor.addConnect( result );
00148 return result;
00149
00150 QF_STACK_POP
00151 }
00152
00153 void SocketServer::close()
00154 { QF_STACK_PUSH(SocketServer::close)
00155
00156 SocketToInfo::iterator i = m_socketToInfo.begin();
00157 for( ; i != m_socketToInfo.end(); ++i )
00158 {
00159 int s = i->first;
00160 socket_close( s );
00161 socket_invalidate( s );
00162 }
00163
00164 QF_STACK_POP
00165 }
00166
00167 bool SocketServer::block( Strategy& strategy, bool poll, double timeout )
00168 { QF_STACK_PUSH(SocketServer::block)
00169
00170 std::set<int> sockets;
00171 SocketToInfo::iterator i = m_socketToInfo.begin();
00172 for( ; i != m_socketToInfo.end(); ++i )
00173 {
00174 if( !socket_isValid(i->first) )
00175 return false;
00176 sockets.insert( i->first );
00177 }
00178
00179 ServerWrapper wrapper( sockets, *this, strategy );
00180 m_monitor.block( wrapper, poll, timeout );
00181 return true;
00182
00183 QF_STACK_POP
00184 }
00185
00186 int SocketServer::socketToPort( int socket )
00187 {
00188 SocketToInfo::iterator find = m_socketToInfo.find( socket );
00189 if( find == m_socketToInfo.end() ) return 0;
00190 return find->second.m_port;
00191 }
00192
00193 int SocketServer::portToSocket( int port )
00194 {
00195 SocketToInfo::iterator find = m_portToInfo.find( port );
00196 if( find == m_portToInfo.end() ) return 0;
00197 return find->second.m_socket;
00198 }
00199 }