cd3c4616c4e35911a43b1b8f4d488d3bedf1bbd7
[anna.git] / include / anna / comm / Socket.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #ifndef anna_comm_Socket_hpp
10 #define anna_comm_Socket_hpp
11
12 #include <unistd.h>
13 #include <sys/socket.h>
14 #include <sys/un.h>
15
16 #include <anna/config/defines.hpp>
17 #include <anna/core/mt/Mutex.hpp>
18
19 #include <anna/comm/INetAddress.hpp>
20 #include <anna/comm/AccessPoint.hpp>
21
22 namespace anna {
23
24 class DataBlock;
25
26 namespace xml {
27 class Node;
28 }
29
30 namespace comm {
31
32 class TransportFactory;
33 class ReceiverFactory;
34
35 /**
36    Esta clase es la superclase de la que heredan todos los socket definidos en este paquete. Es usada tanto para
37    crear socket de la parte cliente y de la parte servidora.
38 */
39 class Socket : public Mutex  {
40 public:
41   /**
42      Tipos de dominios soportados.
43   */
44   struct Domain { enum _v {  Unix = PF_UNIX, Inet = PF_INET } ;  };
45
46   /**
47      Tipos de sockets soportados.
48   */
49   struct Type { enum _v {  Stream = SOCK_STREAM, Datagram = SOCK_DGRAM, Raw = SOCK_RAW } ;  };
50
51   /**
52      Tipos de notificaciones que nos puede indicar el Socket.
53      \see Socket
54   */
55   struct Notify {
56     enum _v {
57       None,          /**< No hay actividad en el socket */
58       ReceiveData,   /**< Datos recibidos */
59       Close,         /**< El extremo remoto ha cerrado el socket */
60       Corrupt        /**< El mensaje recibido no ha sido reconocido por la capa de transporte */
61     };
62   };
63
64   /**
65      Destructor.
66   */
67   virtual ~Socket();
68
69   /**
70      Devuelve el descriptor de fichero asociado a este socket.
71      @return El descriptor de fichero asociado a este socke. Si el socket no ha sido creado devolver�-1.
72   */
73   int getfd() const throw() { return a_fd; }
74
75   /**
76      Devuelve el tipo de socket.
77      \return El tipo de socket.
78   */
79   Type::_v getType() const throw() { return a_type; }
80
81   /**
82      Devuelve el dominio de este socket.
83      \return El dominio de este socket.
84   */
85   Domain::_v getDomain() const throw() { return a_domain; }
86
87   /**
88      Devuelve la categoria asociada a este socket.
89      \return La categoria asociada a este socket.
90   */
91   int getCategory() const throw() { return a_category; }
92
93   /**
94      Informa sobre si el socket es capaz de procesar un determinado protocolo de transporte.
95      \param transportClassName Normalmente se pasara el resultado del metodo \em className de
96      alguno de los protocolos definidos, por ejemplo, Transport::className o
97      LiteTransport::className
98      \return \em true si soporta el nombre de protocolo recibido como parametro o \em false
99      en otro caso.
100   */
101   bool support(const char* transportClassName) const throw();
102
103   /**
104      Devuelve el estado de la conexion de este socket.
105
106      @return \em true si el servidor de socket ha sido conectado o \em false en otro caso.
107   */
108   bool isBound() const throw() { return a_isBound; }
109
110   /**
111      Devuelve el estado del socket.
112      @return \em true si el socket este abierto o \em false en otro caso.
113   */
114   bool isOpened() const throw() { return a_fd != -1; }
115
116   /**
117    * Devuelve \em false si el socket usa un protocolo de comunicaciones seguro o \em false
118    * en otro caso.
119    * \return \em false si el socket usa un protocolo de comunicaciones seguro o \em false
120    * en otro caso.
121    */
122   virtual bool isSecure() const throw() { return false; }
123
124   /**
125      Devuelve la direccion local del socket.
126      \return La direccion local del socket.
127   */
128   const AccessPoint& getLocalAccessPoint() const throw() { return a_localAccessPoint; }
129
130   /**
131      Devuelve la factoria de la capa de transporte usada en este socket.
132      \return la factoria de la capa de transporte usada en este socket.
133   */
134   TransportFactory* getTransportFactory() const throw() { return a_transportFactory; }
135
136   /**
137      Devuelve la factoria de receptores usada en este socket.
138      \return la factoria de receptores usada en este socket.
139   */
140   ReceiverFactory* getReceiverFactory() throw() { return a_receiverFactory; }
141
142   /**
143      Activa o desactiva el modo de bloqueo.
144      \param blockingMode \em true si queremos activar el bloqueo o \em false en otro caso.
145      @return El modo de bloqueo establecido antes de invocar este masodo.
146   */
147   bool setBlockingMode(const bool blockingMode) throw(RuntimeException);
148
149   /**
150      Activa o desactiva el modo de reuso de la direccion.
151      \param reuseMode \em true si queremos activar el reuso o \em false en otro caso.
152      \warning Solo servira para acelerar el uso del socket una vez que el proceso que lo tenia
153      halla dejado de funcionar.
154      \return El modo de reuso establecido antes de invocar a este metodo.
155   */
156   bool setReuseMode(const bool reuseMode) throw(RuntimeException);
157
158   /**
159      Establece la capa de transporte usada en este socket.
160      \warning Exclusivamente uso interno.
161   */
162   void setTransportFactory(TransportFactory* transportFactory)  throw() { a_transportFactory = transportFactory; }
163
164   /**
165      Establece la factoria de receptores usada por este socket.
166      \param receiverFactory Factoria de receptores desde la que obtener el receptor asociado a este Socket.
167   */
168   void setReceiverFactory(ReceiverFactory& receiverFactory)  throw() { a_receiverFactory = &receiverFactory; }
169
170   /**
171      Establece la categoria de este socket.
172      La categoria es una concepto del ambito de la aplicacion que el nucleo de anna.comm
173      no usa para nada. Unicamente hay que tener en cuenta que todos los anna::comm::ClientSocket creados
174      a partir de un anna::comm::ServerSocket comparten su misma categoria.
175      \param category Categoria asociada a este socket.
176   */
177   void setCategory(const int category) throw() { a_category = category; }
178
179   /**
180      Cierra este socket. Si el socket no ha sido creado no tendra ningn efecto.
181   */
182   void close() throw();
183
184   /**
185      Intenta la asociar este socket con los parametros indicados en el constructor.
186   */
187   virtual void bind() throw(RuntimeException);
188
189   /**
190      Devuelve una cadena con la informacion referente a este socket.
191      @return Una cadena con la informacion referente a este socket.
192   */
193   virtual std::string asString() const throw();
194
195   /**
196      Devuelve un nodo XML con la informacion referente a este objeto.
197      \param parent Nodo XML a partir del cual introducir la informacion.
198      \return Un nodo XML con la informacion referente a este objeto.
199   */
200   virtual xml::Node* asXML(xml::Node* parent) const throw(RuntimeException);
201
202 protected:
203   const Domain::_v  a_domain;
204   const Type::_v a_type;
205   int a_fd;
206   AccessPoint a_localAccessPoint;
207   bool a_isBound;
208   TransportFactory* a_transportFactory;
209   ReceiverFactory* a_receiverFactory;
210   int a_category;
211
212   /**
213      Crea un servidor de socket liberado.
214      \param domain Dominio del socket.
215      \param type Tipo de socket.
216      \param transportFactory Factoria de protocolos de transporte a usar por este sockets. Si se indica
217      NULL ser usara el protocolo devuelto por anna::comm::Application::getDefaultTransportFactory.
218      \warning La factoria de protocolos debe estar disponible mientras el Socket este activo.
219   */
220   Socket(const Domain::_v domain, const Type::_v type, TransportFactory* transportFactory = NULL);
221
222   /**
223      Crea un socket INET que sera asociado a la direccion y puerto locales indicados.
224
225      \param localAddress Puede ser usado para limitar la direccion por la que atendiende peticiones un servidor de socket
226      instalado en una maquina con mas de una direccion.
227      \param type Tipo de socket.
228      \param transportFactory Factoria de protocolos de transporte a usar por este sockets. Si se indica
229      NULL ser usara el protocolo devuelto por anna::comm::Application::getDefaultTransportFactory.
230      \warning La factoria de protocolos debe estar disponible mientras el Socket este activo.
231   */
232   Socket(const INetAddress& localAddress,  const Type::_v type, TransportFactory* transportFactory = NULL);
233
234   /**
235      Crea un socket UNIX que sera asociado al archivo indicado como parametro.
236
237      \param path Ruta del archivo que vamos a usar para transferir datos a traves de este socket.
238      \param type Tipo de socket.
239      \param transportFactory Factoria de protocolos de transporte a usar por este sockets. Si se indica
240      NULL ser usara el protocolo devuelto por anna::comm::Application::getDefaultTransportFactory.
241   */
242   Socket(const std::string& path, const Type::_v type, TransportFactory* transportFactory = NULL);
243
244   /**
245      Abre el socket.
246   */
247   void open() throw(RuntimeException);
248
249   /**
250      Cierra este socket. Si el socket no ha sido creado no tendra ningn efecto.
251   */
252   virtual void do_close() throw() { ::close(a_fd); }
253
254   /**
255      Asocia este Socket a la direccion recibida como parametro.
256      \warning Exclusivamente uso interno.
257   */
258   virtual int do_bind(const struct sockaddr*, const int) throw(RuntimeException);
259
260   /**
261      Devuelve la cadena correspondiente a la notificacion recibida como parametro.
262      \param v Codigo de notificacion.
263      \return La cadena correspondiente a la notificacion recibida como parametro.
264   */
265   static const char* asText(const Notify::_v v) throw();
266
267 private:
268   bool a_reuseMode;
269 };
270
271 #define anna_socket_assert(a,b) \
272    if ((a)) { \
273       std::string msg (asString ()); \
274       msg += " | "; \
275       msg += b; \
276       throw RuntimeException (msg, __FILE__, __LINE__); \
277    }
278
279 #define anna_comm_socket_check(a,b) \
280    if ((a) < 0) { \
281       const int xerrno = errno; \
282       std::string msg (asString ()); \
283       msg += " | "; \
284       msg += b; \
285       throw RuntimeException (msg, errno, ANNA_FILE_LOCATION); \
286    }
287 }
288 }
289
290
291 #endif
292
293
294