SocketServer.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 "SocketServer.h"
00027 #include "Utility.h"
00028 #include "Exceptions.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   {
00050   }
00051 
00052   void onEvent( SocketMonitor& monitor, int socket )
00053   {
00054     if( m_sockets.find(socket) != m_sockets.end() )
00055     {
00056       m_strategy.onConnect( m_server, socket, m_server.accept(socket) );
00057     }
00058     else
00059     {
00060       if( !m_strategy.onData( m_server, socket ) )
00061         onError( monitor, socket );
00062     }
00063   }
00064 
00065   void onWrite( SocketMonitor&, int socket )
00066   {
00067     m_strategy.onWrite( m_server, socket );
00068   }
00069 
00070   void onError( SocketMonitor& monitor, int socket )
00071   {
00072     m_strategy.onDisconnect( m_server, socket );
00073     monitor.drop( socket );
00074   }
00075 
00076   void onError( SocketMonitor& )
00077   {
00078     m_strategy.onError( m_server );
00079   }
00080 
00081   void onTimeout( SocketMonitor& )
00082   {
00083     m_strategy.onTimeout( m_server );
00084   };
00085 
00086   typedef std::set<int>
00087     Sockets;
00088 
00089   Sockets m_sockets;
00090   SocketServer& m_server;
00091   SocketServer::Strategy& m_strategy;
00092 };
00093 
00094 SocketServer::SocketServer( int timeout )
00095 : m_monitor( timeout ) {}
00096 
00097 int SocketServer::add( int port, bool reuse, bool noDelay, 
00098                        int sendBufSize, int rcvBufSize )
00099   throw( SocketException& )
00100 {
00101   if( m_portToInfo.find(port) != m_portToInfo.end() )
00102     return m_portToInfo[port].m_socket;
00103 
00104   int socket = socket_createAcceptor( port, reuse );
00105   if( socket < 0 )
00106     throw SocketException();
00107   if( noDelay )
00108     socket_setsockopt( socket, TCP_NODELAY );
00109   if( sendBufSize )
00110     socket_setsockopt( socket, SO_SNDBUF, sendBufSize );
00111   if( rcvBufSize )
00112     socket_setsockopt( socket, SO_RCVBUF, rcvBufSize );
00113   m_monitor.addRead( socket );
00114 
00115   SocketInfo info( socket, port, noDelay, sendBufSize, rcvBufSize );
00116   m_socketToInfo[socket] = info;
00117   m_portToInfo[port] = info;
00118   return socket;
00119 }
00120 
00121 int SocketServer::accept( int socket )
00122 {
00123   SocketInfo info = m_socketToInfo[socket];
00124 
00125   int result = socket_accept( socket );
00126   if( info.m_noDelay )
00127     socket_setsockopt( result, TCP_NODELAY );
00128   if( info.m_sendBufSize )
00129     socket_setsockopt( result, SO_SNDBUF, info.m_sendBufSize );
00130   if( info.m_rcvBufSize )
00131     socket_setsockopt( result, SO_RCVBUF, info.m_rcvBufSize );
00132   if ( result >= 0 )
00133     m_monitor.addConnect( result );
00134   return result;
00135 }
00136 
00137 void SocketServer::close()
00138 {
00139   SocketToInfo::iterator i = m_socketToInfo.begin();
00140   for( ; i != m_socketToInfo.end(); ++i )
00141   {
00142     int s = i->first;
00143     socket_close( s );
00144     socket_invalidate( s );
00145   }
00146 }
00147 
00148 bool SocketServer::block( Strategy& strategy, bool poll, double timeout )
00149 {
00150   std::set<int> sockets;
00151   SocketToInfo::iterator i = m_socketToInfo.begin();
00152   for( ; i != m_socketToInfo.end(); ++i )
00153   {
00154     if( !socket_isValid(i->first) )
00155       return false;
00156     sockets.insert( i->first );
00157   }
00158 
00159   ServerWrapper wrapper( sockets, *this, strategy );
00160   m_monitor.block( wrapper, poll, timeout );
00161   return true;
00162 }
00163 
00164 int SocketServer::socketToPort( int socket )
00165 {
00166   SocketToInfo::iterator find = m_socketToInfo.find( socket );
00167   if( find == m_socketToInfo.end() ) return 0;
00168   return find->second.m_port;
00169 }
00170  
00171 int SocketServer::portToSocket( int port )
00172 {
00173   SocketToInfo::iterator find = m_portToInfo.find( port );
00174   if( find == m_portToInfo.end() ) return 0;
00175   return find->second.m_socket;
00176 }
00177 }

Generated on Mon Sep 15 2014 01:23:55 for QuickFIX by doxygen 1.7.6.1 written by Dimitri van Heesch, © 1997-2001