1 // Copyright (C) 2011 Davis E. King (davis@dlib.net) 2 // License: Boost Software License See LICENSE.txt for the full license. 3 #undef DLIB_BRIDGe_ABSTRACT_ 4 #ifdef DLIB_BRIDGe_ABSTRACT_ 5 6 #include <string> 7 #include "../pipe/pipe_kernel_abstract.h" 8 9 namespace dlib 10 { 11 12 // ---------------------------------------------------------------------------------------- 13 14 struct connect_to_ip_and_port 15 { 16 connect_to_ip_and_port ( 17 const std::string& ip, 18 unsigned short port 19 ); 20 /*! 21 requires 22 - is_ip_address(ip) == true 23 - port != 0 24 ensures 25 - this object will represent a request to make a TCP connection 26 to the given IP address and port number. 27 !*/ 28 }; 29 30 connect_to_ip_and_port connect_to ( 31 const network_address& addr 32 ); 33 /*! 34 requires 35 - addr.port != 0 36 ensures 37 - converts the given network_address object into a connect_to_ip_and_port 38 object. 39 !*/ 40 41 struct listen_on_port 42 { 43 listen_on_port( 44 unsigned short port 45 ); 46 /*! 47 requires 48 - port != 0 49 ensures 50 - this object will represent a request to listen on the given 51 port number for incoming TCP connections. 52 !*/ 53 }; 54 55 template < 56 typename pipe_type 57 > 58 bridge_transmit_decoration<pipe_type> transmit ( 59 pipe_type& p 60 ); 61 /*! 62 requires 63 - pipe_type is some kind of dlib::pipe object 64 - the objects in the pipe must be serializable 65 ensures 66 - Adds a type decoration to the given pipe, marking it as a transmit pipe, and 67 then returns it. 68 !*/ 69 70 template < 71 typename pipe_type 72 > 73 bridge_receive_decoration<pipe_type> receive ( 74 pipe_type& p 75 ); 76 /*! 77 requires 78 - pipe_type is some kind of dlib::pipe object 79 - the objects in the pipe must be serializable 80 ensures 81 - Adds a type decoration to the given pipe, marking it as a receive pipe, and 82 then returns it. 83 !*/ 84 85 // ---------------------------------------------------------------------------------------- 86 87 struct bridge_status 88 { 89 /*! 90 WHAT THIS OBJECT REPRESENTS 91 This simple struct represents the state of a bridge object. A 92 bridge is either connected or not. If it is connected then it 93 is connected to a foreign host with an IP address and port number 94 as indicated by this object. 95 !*/ 96 97 bridge_status( 98 ); 99 /*! 100 ensures 101 - #is_connected == false 102 - #foreign_port == 0 103 - #foreign_ip == "" 104 !*/ 105 106 bool is_connected; 107 unsigned short foreign_port; 108 std::string foreign_ip; 109 }; 110 111 // ---------------------------------------------------------------------------------------- 112 113 class bridge : noncopyable 114 { 115 /*! 116 WHAT THIS OBJECT REPRESENTS 117 This object is a tool for bridging a dlib::pipe object between 118 two network connected applications. 119 120 121 Note also that this object contains a dlib::logger object 122 which will log various events taking place inside a bridge. 123 If you want to see these log messages then enable the logger 124 named "dlib.bridge". 125 126 127 BRIDGE PROTOCOL DETAILS 128 The bridge object creates a single TCP connection between 129 two applications. Whenever it sends an object from a pipe 130 over a TCP connection it sends a byte with the value 1 followed 131 immediately by the serialized copy of the object from the pipe. 132 The serialization is performed by calling the global serialize() 133 function. 134 135 Additionally, a bridge object will periodically send bytes with 136 a value of 0 to ensure the TCP connection remains alive. These 137 are just read and ignored. 138 !*/ 139 140 public: 141 142 bridge ( 143 ); 144 /*! 145 ensures 146 - this object is properly initialized 147 - #get_bridge_status().is_connected == false 148 !*/ 149 150 template <typename T, typename U, typename V> 151 bridge ( 152 T network_parameters, 153 U pipe1, 154 V pipe2 155 ); 156 /*! 157 requires 158 - T is of type connect_to_ip_and_port or listen_on_port 159 - U and V are of type bridge_transmit_decoration or bridge_receive_decoration, 160 however, U and V must be of different types (i.e. one is a receive type and 161 another a transmit type). 162 ensures 163 - this object is properly initialized 164 - performs: reconfigure(network_parameters, pipe1, pipe2) 165 (i.e. using this constructor is identical to using the default constructor 166 and then calling reconfigure()) 167 !*/ 168 169 template <typename T, typename U> 170 bridge ( 171 T network_parameters, 172 U pipe 173 ); 174 /*! 175 requires 176 - T is of type connect_to_ip_and_port or listen_on_port 177 - U is of type bridge_transmit_decoration or bridge_receive_decoration. 178 ensures 179 - this object is properly initialized 180 - performs: reconfigure(network_parameters, pipe) 181 (i.e. using this constructor is identical to using the default constructor 182 and then calling reconfigure()) 183 !*/ 184 185 ~bridge ( 186 ); 187 /*! 188 ensures 189 - blocks until all resources associated with this object have been destroyed. 190 !*/ 191 192 void clear ( 193 ); 194 /*! 195 ensures 196 - returns this object to its default constructed state. That is, it will 197 be inactive, neither maintaining a connection nor attempting to acquire one. 198 - Any active connections or listening sockets will be closed. 199 !*/ 200 201 bridge_status get_bridge_status ( 202 ) const; 203 /*! 204 ensures 205 - returns the current status of this bridge object. In particular, returns 206 an object BS such that: 207 - BS.is_connected == true if and only if the bridge has an active TCP 208 connection to another computer. 209 - if (BS.is_connected) then 210 - BS.foreign_ip == the IP address of the remote host we are connected to. 211 - BS.foreign_port == the port number on the remote host we are connected to. 212 - else if (the bridge has previously been connected to a remote host but hasn't been 213 reconfigured or cleared since) then 214 - BS.foreign_ip == the IP address of the remote host we were connected to. 215 - BS.foreign_port == the port number on the remote host we were connected to. 216 - else 217 - BS.foreign_ip == "" 218 - BS.foreign_port == 0 219 !*/ 220 221 222 223 template < typename T, typename R > 224 void reconfigure ( 225 listen_on_port network_parameters, 226 bridge_transmit_decoration<T> transmit_pipe, 227 bridge_receive_decoration<R> receive_pipe 228 ); 229 /*! 230 ensures 231 - This object will begin listening on the port specified by network_parameters 232 for incoming TCP connections. Any previous bridge state is cleared out. 233 - Onces a connection is established we will: 234 - Stop accepting new connections. 235 - Begin dequeuing objects from the transmit pipe and serializing them over 236 the TCP connection. 237 - Begin deserializing objects from the TCP connection and enqueueing them 238 onto the receive pipe. 239 - if (the current TCP connection is lost) then 240 - This object goes back to listening for a new connection. 241 - if (the receive pipe can contain bridge_status objects) then 242 - Whenever the bridge's status changes the updated bridge_status will be 243 enqueued onto the receive pipe unless the change was a TCP disconnect 244 resulting from a user calling reconfigure(), clear(), or destructing this 245 bridge. The status contents are defined by get_bridge_status(). 246 throws 247 - socket_error 248 This exception is thrown if we are unable to open the listening socket. 249 !*/ 250 template < typename T, typename R > 251 void reconfigure ( 252 listen_on_port network_parameters, 253 bridge_receive_decoration<R> receive_pipe, 254 bridge_transmit_decoration<T> transmit_pipe 255 ); 256 /*! 257 ensures 258 - performs reconfigure(network_parameters, transmit_pipe, receive_pipe) 259 !*/ 260 template < typename T > 261 void reconfigure ( 262 listen_on_port network_parameters, 263 bridge_transmit_decoration<T> transmit_pipe 264 ); 265 /*! 266 ensures 267 - This function is identical to the above two reconfigure() functions 268 except that there is no receive pipe. 269 !*/ 270 template < typename R > 271 void reconfigure ( 272 listen_on_port network_parameters, 273 bridge_receive_decoration<R> receive_pipe 274 ); 275 /*! 276 ensures 277 - This function is identical to the above three reconfigure() functions 278 except that there is no transmit pipe. 279 !*/ 280 281 282 283 template <typename T, typename R> 284 void reconfigure ( 285 connect_to_ip_and_port network_parameters, 286 bridge_transmit_decoration<T> transmit_pipe, 287 bridge_receive_decoration<R> receive_pipe 288 ); 289 /*! 290 ensures 291 - This object will begin making TCP connection attempts to the IP address and port 292 specified by network_parameters. Any previous bridge state is cleared out. 293 - Onces a connection is established we will: 294 - Stop attempting new connections. 295 - Begin dequeuing objects from the transmit pipe and serializing them over 296 the TCP connection. 297 - Begin deserializing objects from the TCP connection and enqueueing them 298 onto the receive pipe. 299 - if (the current TCP connection is lost) then 300 - This object goes back to attempting to make a TCP connection with the 301 IP address and port specified by network_parameters. 302 - if (the receive pipe can contain bridge_status objects) then 303 - Whenever the bridge's status changes the updated bridge_status will be 304 enqueued onto the receive pipe unless the change was a TCP disconnect 305 resulting from a user calling reconfigure(), clear(), or destructing this 306 bridge. The status contents are defined by get_bridge_status(). 307 !*/ 308 template <typename T, typename R> 309 void reconfigure ( 310 connect_to_ip_and_port network_parameters, 311 bridge_receive_decoration<R> receive_pipe, 312 bridge_transmit_decoration<T> transmit_pipe 313 ); 314 /*! 315 ensures 316 - performs reconfigure(network_parameters, transmit_pipe, receive_pipe) 317 !*/ 318 template <typename T> 319 void reconfigure ( 320 connect_to_ip_and_port network_parameters, 321 bridge_transmit_decoration<T> transmit_pipe 322 ); 323 /*! 324 ensures 325 - This function is identical to the above two reconfigure() functions 326 except that there is no receive pipe. 327 !*/ 328 template <typename R> 329 void reconfigure ( 330 connect_to_ip_and_port network_parameters, 331 bridge_receive_decoration<R> receive_pipe 332 ); 333 /*! 334 ensures 335 - This function is identical to the above three reconfigure() functions 336 except that there is no transmit pipe. 337 !*/ 338 339 }; 340 341 // ---------------------------------------------------------------------------------------- 342 343 } 344 345 #endif // DLIB_BRIDGe_ABSTRACT_ 346 347 348