1 // ANNA - Anna is Not Nothingness Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // http://redmine.teslayout.com/projects/anna-suite
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
37 #ifndef anna_comm_ServerSocket_hpp
38 #define anna_comm_ServerSocket_hpp
40 #include <anna/core/util/Recycler.hpp>
41 #include <anna/core/util/Millisecond.hpp>
43 #include <anna/comm/Socket.hpp>
44 #include <anna/comm/internal/LocalConnection.hpp>
54 Esta clase implementa el servidor de Socket. Un servidor de Socket espera las peticiones de entrada procedentes
55 de la red y realiza las operaciones necesarias para tratar la operacion y posiblemente devolver un resultado
58 El 'backlog' de un servidor de socket define la longitud maxima que la cola de mensajes pendientes puede alcanzar.
59 Si cliente realiza una peticion mediante una conexion UF_UNIX cuando la cola de mensajes del servidor esta llena
60 recibira un error ECONNREFUSED, aunque normalmente el protocolo subyacente se encarga de retransmitir la peticion
61 un numero indeterminado de veces.
63 @see Communicator::accept
65 class ServerSocket : public Socket {
68 numero de milisegundos por defecto que espera antes de dar por fallida una asociacion a una
71 static const Millisecond DefaultBindDelay;
73 typedef Recycler<LocalConnection>::iterator iterator;
76 Tamao de la cola de mensajes tomado por defecto.
78 static const int defaultBacklog = 30;
81 Crea un servidor de socket liberado.
82 \param transportFactory Factoria de protocolos de transporte a usar por este sockets.
83 \param domain Dominio del socket.
84 \param type Tipo de socket.
85 \warning La Factoria de protocolos debe estar disponible mientras el Socket esta activo.
87 ServerSocket(TransportFactory* transportFactory = NULL, Domain::_v domain = Socket::Domain::Inet, Type::_v type = Socket::Type::Stream) :
88 Socket(domain, type, transportFactory),
89 a_backlog(defaultBacklog),
92 a_msBindDelay(DefaultBindDelay) {}
95 Crea un servidor de socket conectado a la direccion y puerto indicado y con la longitud de cola maxima indicada.
97 \param localAddress Direccion Local en la que atendera las peticiones.
98 \param transportFactory Factoria de protocolos de transporte a usar por este sockets.
99 \param sharedBind \em true Si puede haber mas de una aplicacion escuchando es esta misma direccion.
100 \warning La factoria de protocolos debe estar disponible mientras el Socket esta activo.
102 ServerSocket(const INetAddress& localAddress, const bool sharedBind, TransportFactory* transportFactory = NULL) :
103 Socket(localAddress, Socket::Type::Stream, transportFactory),
104 a_backlog(defaultBacklog),
105 a_sharedBind(sharedBind),
106 a_binderSocket(NULL),
107 a_msBindDelay(DefaultBindDelay) {}
112 virtual ~ServerSocket();
115 Devuelve el numero de milisegundos esperado al hacer el bind compartido con este sockets
116 antes de considerar que no se puede atender peticiones en esa direccion.
117 \return el numero de milisegundos esperado al hacer el bind compartido con este sockets
118 antes de considerar que no se puede atender peticiones en esa direccion.
120 const Millisecond &getBindDelay() throw() { return a_msBindDelay; }
123 Devuelve el socket asociado a este socket de bind compartido.
124 \return El socket asociado a este socket de bind compartido. Puede ser NULL.
126 BinderSocket* getBinderSocket() throw() { return a_binderSocket; }
129 Devuelve el modo de asociacion de este socket.
130 \return El modo de asociacion de este socket.
131 \warning El valor devuelto por este metodo solo sera valido despues de ejecutar correctamente
134 bool isSharedBind() const throw() { return a_sharedBind; }
137 Establece el tamao de la cola de mensajes.
138 \param backlog Tamao de la cola de mensajes.
140 void setBacklog(const int backlog) throw() { a_backlog = backlog; }
143 Establece el numero de milisegundos esperado al hacer el bind con este sockets antes
144 de considerar que no se puede realizar la conexion.
146 \param bindDelay numero de milisegundos esperado al hacer la conexion con este
147 sockets antes de considerar que no se puede realizar la conexion.
149 \see #DefaultBindDelay
151 \warning Solo tendra efecto en el caso de que el socket tenga activado el modo de 'Bind compartido'.
153 void setBindDelay(const Millisecond &bindDelay) throw() { a_msBindDelay = bindDelay; }
156 Metodo que debemos invocar una vez que el ServerSocket esta establecido.
157 \warning Normalmente se invocar�desde Communicator::attach(ServerSocket&,bool)
159 virtual void prepare() throw(RuntimeException);
162 Comprueba la conexion establecida y acepta las peticiones. Esta funcin puede bloquear al thread
163 que la invoca mientras no llegue una peticion de apertura de conexion si no hemos establecido el modo
164 no-bloqueante del socket. Ver Socket::setBlockingMode.
166 Cada uno de los socket obtenidos con este Metodo debe ser liberado con #release cuando ya no sean
169 @return Nueva conexion aceptada, pendiente de pasar los filtros de acceptacion.
171 \warning Exclusivamente uso interno.
173 LocalConnection* accept() throw(RuntimeException);
176 Libera los recursos del socket recibido como parametro.
178 @param localConnection Socket del que vamos a liberar los recursos. Esta instancia deberia haberse obtenido
179 mediante el Metodo #accept, ya que en otro caso los resultados no estan definidos.
181 \warning Exclusivamente uso interno.
183 void release(LocalConnection* localConnection) throw(RuntimeException);
186 Devuelve un iterador al primer LocalConnection definido.
187 \return un iterador al primer LocalConnection definido.
189 iterator begin() throw() { return a_localConnections.begin(); }
192 Devuelve un iterador al ultimo LocalConnection definido.
193 \return un iterador al ultimo LocalConnection definido.
195 iterator end() throw() { return a_localConnections.end(); }
198 Devuelve una cadena con la informacion referente a este socket.
199 @return Una cadena con la informacion referente a este socket.
201 virtual std::string asString() const throw();
204 Devuelve un nodo XML con la informacion referente a este objeto.
205 \param parent Nodo XML a partir del cual introducir la informacion.
206 \return Un nodo XML con la informacion referente a este objeto.
208 virtual xml::Node* asXML(xml::Node* parent) const throw(RuntimeException);
211 Metodo manejador de evento que permite ajustar el funcionamiento cuando el nucleo de
212 anna.comm notifica que ha detectado una peticion de conexion desde un proceso
213 remoto a un ServerSocket asociado al comunicador. Permite independencia de dicho
214 comunicador y complementa el control de aceptacion (por defecto, se devuelve true
215 para no influir en la implementacion del metodo analogo en el comunicador).
217 @param clientSocket Socket cliente que solicita acceso.
219 \return \em true si la conexion es acceptada a \em false en otro caso, en cuyo caso se liberaran
220 automaticamente todos los recursos asociados a la peticion de conexion.
222 virtual bool eventAcceptConnection(const ClientSocket &clientSocket) throw(RuntimeException) { return true; }
225 // Informa sobre la rotura de una conexion que se creo a partir de un ServerSocket
227 // @param localConnection Socket que se acepto sobre el server socket y que se ha roto.
229 // virtual void eventBreakLocalConnection (LocalConnection* localConnection) throw (RuntimeException) {;}
233 Devuelve una referencia al contenido apuntado por el iterador.
234 \return una referencia al contenido apuntado por el iterador.
236 static LocalConnection* localConnection(iterator& ii) throw() { return Recycler<LocalConnection>::data(ii); }
239 Devuelve el nombre logico de esta clase.
240 \return el nombre logico de esta clase.
242 static const char* className() throw() { return "anna::comm::ServerSocket"; }
246 Crea un servidor de socket conectado a la direccion y puerto indicado y con la longitud de cola maxima indicada.
248 \param transportFactory Factoria de protocolos de transporte a usar por este sockets.
249 \param localAddress Puede ser usado para limitar la direccion por la que atendiende peticiones un servidor de socket
250 instalado en una maquina con mas de una direccion.
251 \param sharedBind \em true Si puede haber mas de una aplicacion escuchando es esta misma direccion.
252 \param type Tipo de socket.
253 \warning La Factoria de protocolos debe estar disponible mientras el Socket esta activo.
255 ServerSocket(const INetAddress& localAddress, const bool sharedBind, Type::_v type, TransportFactory* transportFactory = NULL) :
256 Socket(localAddress, type, transportFactory),
257 a_backlog(defaultBacklog),
259 a_binderSocket(NULL),
260 a_msBindDelay(DefaultBindDelay) {}
264 Recycler <LocalConnection> a_localConnections;
265 const bool a_sharedBind;
266 BinderSocket* a_binderSocket;
267 Millisecond a_msBindDelay;
269 virtual ClientSocket* allocateClientSocket() const throw();
270 int do_bind(const struct sockaddr *, const int len) throw(RuntimeException);
272 friend class BinderSocket;