- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gmultiserver.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2013 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // gmultiserver.cpp
19 //
20
21 #include "gdef.h"
22 #include "gnet.h"
23 #include "gmultiserver.h"
24 #include "glog.h"
25 #include "gassert.h"
26 #include "gmemory.h"
27 #include <list>
28 #include <algorithm> // std::swap
29 #include <utility> // std::swap
30
31 bool GNet::MultiServer::canBind( const AddressList & address_list , bool do_throw )
32 {
33 for( AddressList::const_iterator p = address_list.begin() ; p != address_list.end() ; ++p )
34 {
35 if( ! Server::canBind( *p , do_throw ) )
36 return false ;
37 }
38 return true ;
39 }
40
41 GNet::MultiServer::AddressList GNet::MultiServer::addressList( const Address & address )
42 {
43 AddressList result ;
44 result.push_back( address ) ;
45 return result ;
46 }
47
48 GNet::MultiServer::AddressList GNet::MultiServer::addressList( const AddressList & list , unsigned int port )
49 {
50 AddressList result( list ) ;
51 if( result.empty() )
52 {
53 result.push_back( GNet::Address(port) ) ;
54 }
55 else
56 {
57 for( AddressList::iterator p = result.begin() ; p != result.end() ; ++p )
58 (*p).setPort( port ) ;
59 }
60 return result ;
61 }
62
63 GNet::MultiServer::AddressList GNet::MultiServer::addressList( const G::Strings & list , unsigned int port )
64 {
65 AddressList result ;
66 if( list.empty() )
67 {
68 result.push_back( GNet::Address(port) ) ;
69 }
70 else
71 {
72 for( G::Strings::const_iterator p = list.begin() ; p != list.end() ; ++p )
73 {
74 if( (*p).empty() )
75 result.push_back( GNet::Address(port) ) ;
76 else
77 result.push_back( GNet::Address(*p,port) ) ;
78 }
79 }
80 return result ;
81 }
82
83 GNet::MultiServer::MultiServer( const AddressList & address_list , bool use_connection_lookup )
84 {
85 if( use_connection_lookup )
86 m_connection_lookup <<= new GNet::ConnectionLookup ;
87
88 G_ASSERT( ! address_list.empty() ) ;
89 for( AddressList::const_iterator p = address_list.begin() ; p != address_list.end() ; ++p )
90 {
91 init( *p , m_connection_lookup.get() ) ;
92 }
93 }
94
95 GNet::MultiServer::MultiServer()
96 {
97 }
98
99 void GNet::MultiServer::init( const AddressList & address_list )
100 {
101 G_ASSERT( ! address_list.empty() ) ;
102 for( AddressList::const_iterator p = address_list.begin() ; p != address_list.end() ; ++p )
103 {
104 init( *p , NULL ) ;
105 }
106 }
107
108 void GNet::MultiServer::init( const Address & address , ConnectionLookup * connection_lookup )
109 {
110 // note that the Ptr class does not have proper value semantics...
111 MultiServerPtr ptr( new MultiServerImp(*this,address,connection_lookup) ) ;
112 m_server_list.push_back( MultiServerPtr() ) ; // copy a null pointer into the list
113 m_server_list.back().swap( ptr ) ;
114 }
115
116 GNet::MultiServer::~MultiServer()
117 {
118 serverCleanup() ;
119 }
120
121 void GNet::MultiServer::serverCleanup()
122 {
123 for( List::iterator p = m_server_list.begin() ; p != m_server_list.end() ; ++p )
124 {
125 try
126 {
127 (*p).get()->cleanup() ;
128 }
129 catch(...) // dtor
130 {
131 }
132 }
133 }
134
135 void GNet::MultiServer::serverReport( const std::string & type ) const
136 {
137 for( List::const_iterator p = m_server_list.begin() ; p != m_server_list.end() ; ++p )
138 {
139 const Server & server = *((*p).get()) ;
140 G_LOG_S( "GNet::MultiServer: " << type << " server on " << server.address().second.displayString() ) ;
141 }
142 }
143
144 std::pair<bool,GNet::Address> GNet::MultiServer::firstAddress() const
145 {
146 std::pair<bool,GNet::Address> result( false , GNet::Address::invalidAddress() ) ;
147 for( List::const_iterator p = m_server_list.begin() ; p != m_server_list.end() ; ++p )
148 {
149 if( (*p).get()->address().first )
150 {
151 result.first = true ;
152 result.second = (*p).get()->address().second ;
153 break ;
154 }
155 }
156 return result ;
157 }
158
159 // ==
160
161 GNet::MultiServerImp::MultiServerImp( MultiServer & ms , const Address & address ,
162 ConnectionLookup * connection_lookup ) :
163 Server(address,connection_lookup) ,
164 m_ms(ms)
165 {
166 }
167
168 GNet::ServerPeer * GNet::MultiServerImp::newPeer( PeerInfo peer_info )
169 {
170 return m_ms.newPeer( peer_info ) ;
171 }
172
173 void GNet::MultiServerImp::cleanup()
174 {
175 serverCleanup() ;
176 }
177
178 // ==
179
180 GNet::MultiServerPtr::MultiServerPtr( ServerImp * p ) :
181 m_p(p)
182 {
183 }
184
185 GNet::MultiServerPtr::MultiServerPtr( const MultiServerPtr & other ) :
186 m_p(other.m_p)
187 {
188 }
189
190 GNet::MultiServerPtr::~MultiServerPtr()
191 {
192 delete m_p ;
193 }
194
195 void GNet::MultiServerPtr::operator=( const MultiServerPtr & rhs )
196 {
197 m_p = rhs.m_p ;
198 }
199
200 void GNet::MultiServerPtr::swap( MultiServerPtr & other )
201 {
202 std::swap( other.m_p , m_p ) ;
203 }
204
205 GNet::MultiServerImp * GNet::MultiServerPtr::get()
206 {
207 return m_p ;
208 }
209
210 const GNet::MultiServerImp * GNet::MultiServerPtr::get() const
211 {
212 return m_p ;
213 }
214
GNet::MultiServerPtr::MultiServerPtr
MultiServerPtr(ServerImp *=NULL)
Constructor.
Definition: gmultiserver.cpp:180
G_LOG_S
#define G_LOG_S(expr)
Definition: glog.h:103
GNet::MultiServer::addressList
static AddressList addressList(const Address &)
A trivial convenience fuction that returns the given addresses as a single-element list...
Definition: gmultiserver.cpp:41
GNet::ServerPeer
An abstract base class for the GNet::Server's connection to a remote client.
Definition: gserver.h:191
GNet::Server::canBind
static bool canBind(const Address &listening_address, bool do_throw)
Checks that the specified address can be bound.
Definition: gserver.cpp:172
GNet::MultiServerPtr
A private implementation class used by GNet::MultiServer.
Definition: gmultiserver.h:68
GNet::MultiServer::MultiServer
MultiServer()
Default constructor. Initialise with init().
Definition: gmultiserver.cpp:95
glog.h
GNet::MultiServerPtr::swap
void swap(MultiServerPtr &)
Swaps internals with the other.
Definition: gmultiserver.cpp:200
G::Strings
std::list< std::string > Strings
A std::list of std::strings.
Definition: gstrings.h:39
GNet::MultiServerPtr::get
MultiServerImp * get()
Returns the raw pointer.
Definition: gmultiserver.cpp:205
GNet::Address
The Address class encapsulates an IP transport address.
Definition: gaddress.h:48
GNet::Address::invalidAddress
static Address invalidAddress()
Returns an invalid address.
Definition: gaddress_ipv4.cpp:458
gmultiserver.h
GNet::ConnectionLookup
A class for getting more information about a connection from the operating system.
Definition: gconnectionlookup.h:42
GNet::Server
A network server class which listens on a specific port and spins off ServerPeer objects for each inc...
Definition: gserver.h:83
GNet::MultiServerImp::newPeer
virtual ServerPeer * newPeer(PeerInfo)
Server peer factory method.
Definition: gmultiserver.cpp:168
GNet::MultiServer::canBind
static bool canBind(const AddressList &listening_address_list, bool do_throw)
Checks that the specified addresses can be bound.
Definition: gmultiserver.cpp:31
G_ASSERT
#define G_ASSERT(test)
Definition: gassert.h:30
gassert.h
GNet::MultiServerImp::cleanup
void cleanup()
Does cleanup.
Definition: gmultiserver.cpp:173
GNet::MultiServer::~MultiServer
virtual ~MultiServer()
Destructor.
Definition: gmultiserver.cpp:116
GNet::MultiServerImp
A private implementation class used by GNet::MultiServer.
Definition: gmultiserver.h:43
GNet::MultiServer::init
void init(const AddressList &address_list)
Initilisation after default construction.
Definition: gmultiserver.cpp:99
GNet::MultiServerImp::MultiServerImp
MultiServerImp(MultiServer &ms, const Address &, ConnectionLookup *)
Constructor.
Definition: gmultiserver.cpp:161
GNet::MultiServer::AddressList
std::list< Address > AddressList
Definition: gmultiserver.h:105
GNet::MultiServer::serverCleanup
void serverCleanup()
Should be called from all derived classes' destructors so that peer objects can use their Server obje...
Definition: gmultiserver.cpp:121
GNet::MultiServerPtr::~MultiServerPtr
~MultiServerPtr()
Destructor.
Definition: gmultiserver.cpp:190
GNet::MultiServer
A server that listens on more than one interface using a facade pattern to multiple Server instances...
Definition: gmultiserver.h:102
GNet::MultiServer::firstAddress
std::pair< bool, Address > firstAddress() const
Returns the first listening address.
Definition: gmultiserver.cpp:144
gmemory.h
GNet::Server::PeerInfo
A structure used in GNet::Server::newPeer().
Definition: gserver.h:91
GNet::Server::address
std::pair< bool, Address > address() const
Returns the listening address.
Definition: gserver.cpp:221
GNet::MultiServer::serverReport
void serverReport(const std::string &server_type) const
Writes to the system log a summary of the underlying server objects and their addresses.
Definition: gmultiserver.cpp:135
GNet::MultiServerPtr::operator=
void operator=(const MultiServerPtr &)
Assignment operator.
Definition: gmultiserver.cpp:195