// Copyright (C) 2011 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #undef DLIB_BRIDGe_ABSTRACT_ #ifdef DLIB_BRIDGe_ABSTRACT_ #include <string> #include "../pipe/pipe_kernel_abstract.h" namespace dlib { // ---------------------------------------------------------------------------------------- struct connect_to_ip_and_port { connect_to_ip_and_port ( const std::string& ip, unsigned short port ); /*! requires - is_ip_address(ip) == true - port != 0 ensures - this object will represent a request to make a TCP connection to the given IP address and port number. !*/ }; connect_to_ip_and_port connect_to ( const network_address& addr ); /*! requires - addr.port != 0 ensures - converts the given network_address object into a connect_to_ip_and_port object. !*/ struct listen_on_port { listen_on_port( unsigned short port ); /*! requires - port != 0 ensures - this object will represent a request to listen on the given port number for incoming TCP connections. !*/ }; template < typename pipe_type > bridge_transmit_decoration<pipe_type> transmit ( pipe_type& p ); /*! requires - pipe_type is some kind of dlib::pipe object - the objects in the pipe must be serializable ensures - Adds a type decoration to the given pipe, marking it as a transmit pipe, and then returns it. !*/ template < typename pipe_type > bridge_receive_decoration<pipe_type> receive ( pipe_type& p ); /*! requires - pipe_type is some kind of dlib::pipe object - the objects in the pipe must be serializable ensures - Adds a type decoration to the given pipe, marking it as a receive pipe, and then returns it. !*/ // ---------------------------------------------------------------------------------------- struct bridge_status { /*! WHAT THIS OBJECT REPRESENTS This simple struct represents the state of a bridge object. A bridge is either connected or not. If it is connected then it is connected to a foreign host with an IP address and port number as indicated by this object. !*/ bridge_status( ); /*! ensures - #is_connected == false - #foreign_port == 0 - #foreign_ip == "" !*/ bool is_connected; unsigned short foreign_port; std::string foreign_ip; }; // ---------------------------------------------------------------------------------------- class bridge : noncopyable { /*! WHAT THIS OBJECT REPRESENTS This object is a tool for bridging a dlib::pipe object between two network connected applications. Note also that this object contains a dlib::logger object which will log various events taking place inside a bridge. If you want to see these log messages then enable the logger named "dlib.bridge". BRIDGE PROTOCOL DETAILS The bridge object creates a single TCP connection between two applications. Whenever it sends an object from a pipe over a TCP connection it sends a byte with the value 1 followed immediately by the serialized copy of the object from the pipe. The serialization is performed by calling the global serialize() function. Additionally, a bridge object will periodically send bytes with a value of 0 to ensure the TCP connection remains alive. These are just read and ignored. !*/ public: bridge ( ); /*! ensures - this object is properly initialized - #get_bridge_status().is_connected == false !*/ template <typename T, typename U, typename V> bridge ( T network_parameters, U pipe1, V pipe2 ); /*! requires - T is of type connect_to_ip_and_port or listen_on_port - U and V are of type bridge_transmit_decoration or bridge_receive_decoration, however, U and V must be of different types (i.e. one is a receive type and another a transmit type). ensures - this object is properly initialized - performs: reconfigure(network_parameters, pipe1, pipe2) (i.e. using this constructor is identical to using the default constructor and then calling reconfigure()) !*/ template <typename T, typename U> bridge ( T network_parameters, U pipe ); /*! requires - T is of type connect_to_ip_and_port or listen_on_port - U is of type bridge_transmit_decoration or bridge_receive_decoration. ensures - this object is properly initialized - performs: reconfigure(network_parameters, pipe) (i.e. using this constructor is identical to using the default constructor and then calling reconfigure()) !*/ ~bridge ( ); /*! ensures - blocks until all resources associated with this object have been destroyed. !*/ void clear ( ); /*! ensures - returns this object to its default constructed state. That is, it will be inactive, neither maintaining a connection nor attempting to acquire one. - Any active connections or listening sockets will be closed. !*/ bridge_status get_bridge_status ( ) const; /*! ensures - returns the current status of this bridge object. In particular, returns an object BS such that: - BS.is_connected == true if and only if the bridge has an active TCP connection to another computer. - if (BS.is_connected) then - BS.foreign_ip == the IP address of the remote host we are connected to. - BS.foreign_port == the port number on the remote host we are connected to. - else if (the bridge has previously been connected to a remote host but hasn't been reconfigured or cleared since) then - BS.foreign_ip == the IP address of the remote host we were connected to. - BS.foreign_port == the port number on the remote host we were connected to. - else - BS.foreign_ip == "" - BS.foreign_port == 0 !*/ template < typename T, typename R > void reconfigure ( listen_on_port network_parameters, bridge_transmit_decoration<T> transmit_pipe, bridge_receive_decoration<R> receive_pipe ); /*! ensures - This object will begin listening on the port specified by network_parameters for incoming TCP connections. Any previous bridge state is cleared out. - Onces a connection is established we will: - Stop accepting new connections. - Begin dequeuing objects from the transmit pipe and serializing them over the TCP connection. - Begin deserializing objects from the TCP connection and enqueueing them onto the receive pipe. - if (the current TCP connection is lost) then - This object goes back to listening for a new connection. - if (the receive pipe can contain bridge_status objects) then - Whenever the bridge's status changes the updated bridge_status will be enqueued onto the receive pipe unless the change was a TCP disconnect resulting from a user calling reconfigure(), clear(), or destructing this bridge. The status contents are defined by get_bridge_status(). throws - socket_error This exception is thrown if we are unable to open the listening socket. !*/ template < typename T, typename R > void reconfigure ( listen_on_port network_parameters, bridge_receive_decoration<R> receive_pipe, bridge_transmit_decoration<T> transmit_pipe ); /*! ensures - performs reconfigure(network_parameters, transmit_pipe, receive_pipe) !*/ template < typename T > void reconfigure ( listen_on_port network_parameters, bridge_transmit_decoration<T> transmit_pipe ); /*! ensures - This function is identical to the above two reconfigure() functions except that there is no receive pipe. !*/ template < typename R > void reconfigure ( listen_on_port network_parameters, bridge_receive_decoration<R> receive_pipe ); /*! ensures - This function is identical to the above three reconfigure() functions except that there is no transmit pipe. !*/ template <typename T, typename R> void reconfigure ( connect_to_ip_and_port network_parameters, bridge_transmit_decoration<T> transmit_pipe, bridge_receive_decoration<R> receive_pipe ); /*! ensures - This object will begin making TCP connection attempts to the IP address and port specified by network_parameters. Any previous bridge state is cleared out. - Onces a connection is established we will: - Stop attempting new connections. - Begin dequeuing objects from the transmit pipe and serializing them over the TCP connection. - Begin deserializing objects from the TCP connection and enqueueing them onto the receive pipe. - if (the current TCP connection is lost) then - This object goes back to attempting to make a TCP connection with the IP address and port specified by network_parameters. - if (the receive pipe can contain bridge_status objects) then - Whenever the bridge's status changes the updated bridge_status will be enqueued onto the receive pipe unless the change was a TCP disconnect resulting from a user calling reconfigure(), clear(), or destructing this bridge. The status contents are defined by get_bridge_status(). !*/ template <typename T, typename R> void reconfigure ( connect_to_ip_and_port network_parameters, bridge_receive_decoration<R> receive_pipe, bridge_transmit_decoration<T> transmit_pipe ); /*! ensures - performs reconfigure(network_parameters, transmit_pipe, receive_pipe) !*/ template <typename T> void reconfigure ( connect_to_ip_and_port network_parameters, bridge_transmit_decoration<T> transmit_pipe ); /*! ensures - This function is identical to the above two reconfigure() functions except that there is no receive pipe. !*/ template <typename R> void reconfigure ( connect_to_ip_and_port network_parameters, bridge_receive_decoration<R> receive_pipe ); /*! ensures - This function is identical to the above three reconfigure() functions except that there is no transmit pipe. !*/ }; // ---------------------------------------------------------------------------------------- } #endif // DLIB_BRIDGe_ABSTRACT_