347 lines
13 KiB
C++
347 lines
13 KiB
C++
// 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_
|
|
|
|
|