nidas  v1.2-1520
Public Member Functions | Private Member Functions | Private Attributes | Friends | List of all members
nidas::util::McSocket< SocketT > Class Template Reference

A McSocket provides a way to establish a TCP stream socket connection, or a pair of UDP datagram sockets using a common port number. More...

#include <McSocket.h>

Inheritance diagram for nidas::util::McSocket< SocketT >:
Inheritance graph
[legend]

Public Member Functions

 McSocket ()
 Create a McSocket for requesting or accepting multicast requests for a socket connection. More...
 
 McSocket (const McSocket< SocketT > &)
 Copy constructor. More...
 
McSocket< SocketT > & operator= (const McSocket< SocketT > &rhs)
 Assignment operator. More...
 
virtual ~McSocket ()
 
void setInterface (Inet4NetworkInterface iaddr)
 Set a specific interface for the multicasts. More...
 
Inet4NetworkInterface getInterface () const
 
std::list< Inet4NetworkInterfacegetInterfaces () const throw (IOException)
 Return all network interfaces on this system. More...
 
const Inet4SocketAddressgetInet4McastSocketAddress () const
 Get the multicast address for listening to requests. More...
 
void setInet4McastSocketAddress (const Inet4SocketAddress &val)
 Set the multicast address for listening to requests. More...
 
void setRequestType (int val)
 Set the request type value. More...
 
int getRequestType () const
 Get the request type number. More...
 
void listen () throw (IOException)
 Register with a McSocketListener to listen on the multicast address. More...
 
SocketT * accept (Inet4PacketInfoX &) throw (IOException)
 Like ServerSocket::accept(), this method will return a connected socket. More...
 
virtual void connected (SocketT *, const Inet4PacketInfoX &)
 Virtual method that is called when a socket connection is established. More...
 
void request () throw (IOException)
 Start issuing requests for a connection by multicasting McSocketDatagrams. More...
 
SocketT * connect (Inet4PacketInfoX &) throw (IOException)
 Do a request(), and then wait until a TCP connection is established, or a UDP datagram is received back. More...
 
virtual void close () throw (IOException)
 Unregister this McSocket from the multicasting and listening threads. More...
 

Private Member Functions

void offer (SocketT *sock, const Inet4PacketInfoX &pktinfo)
 How a McSocketListener passes back a connected TCP socket or DatagramSocket. More...
 
void offer (int err)
 
void joinMulticaster ()
 

Private Attributes

Inet4SocketAddress _mcastAddr
 
Inet4NetworkInterface _iface
 
int _requestType
 
Cond _connectCond
 
SocketT * _newsocket
 
Inet4PacketInfoX _newpktinfo
 
bool _socketOffered
 
int _offerErrno
 
Thread_multicaster
 The thread we start which multicasts for connections. More...
 
Mutex _multicaster_mutex
 

Friends

class McSocketListener
 McSocketListener and McSocketMulticaster are friends that setup the socket connection and call the private offer() method. More...
 
template<class SocketTT >
class McSocketMulticaster
 

Detailed Description

template<class SocketT>
class nidas::util::McSocket< SocketT >

A McSocket provides a way to establish a TCP stream socket connection, or a pair of UDP datagram sockets using a common port number.

The communication is esablished by multicasting a request for the service. Contained in the multicast datagram is an integer value for the type of service requested, allowing this protocol to be used for any type of service that can be provided over TCP or UDP sockets.

Use a McSocket<Socket> to establish a TCP SOCK_STREAM connection. Use a McSocket<DatagramSocket> to establish a pair of UDP SOCK_DGRAM sockets.

McSocket is used to establish the connection at either end. A McSocket can either listen for a connection (like a ServerSocket) or connect to a remote McSocket.

When McSocket does a connect(), it starts a McSocketMulticaster thread. This thread creates either a ServerSocket (for McSocket<Socket>) or a DatagramSocket (for McSocket<DatagramSocket>), using any available port number. Then it multicasts McSocketDatagrams containing the request type of the McSocket, the socket type (SOCK_STREAM or SOCK_DGRAM), and the port number of the ServerSocket or DatagramSocket. When a select indicates that data is readable on the created socket, then the McSocketMulticaster passes the accepted socket back to the McSocket as the return value of the connect() method. The McSocketMulticaster thread then quits. This connection can also be established asynchronously in a two-step sequence using request() and connected() instead of connect().

When a McSocket does an accept(), it registers itself with a McSocketListener, a thread which is listening for McSocketDatagrams on a multicast address. When the McSocketListener receives a McSocketDatagram, it checks if a McSocket has requested a connection for the given request type and socket type. If so, then it creates a Socket or DatagramSocket and connects it to the socket port on the requesting host. This Socket is returned as the value of the accept() method. This connection can also be established asynchronously in a two-step sequence using listen() and connected() instead of accept().

Constructor & Destructor Documentation

template<class SocketT >
nidas::util::McSocket< SocketT >::McSocket ( )

Create a McSocket for requesting or accepting multicast requests for a socket connection.

Typical usage:

Inet4Address mcastAddr = Inet4Address::getByName("239.0.0.10");
int mport = 10000;
Inet4SocketAddress mcastSockAddr(mcastAddr,mport);
int rtype = 99;
McSocket<Socket> server;
server.setInet4McastSocketAddress(mcastSockAddr);
server.setRequestType(rtype);
McSocket<Socket> client;
client.setInet4McastSocketAddress(mcastSockAddr);
client.setRequestType(rtype);
class McThread: public Thread {
public:
McThread(McSocket<Socket>& clnt):
Thread("McThread"),client(clnt) {}
int run() throw(Exception)
{
Socket* socket = client.connect();
char buf[16];
size_t l = socket->recv(buf,sizeof(buf));
buf[l] = '\0';
cerr << "requester read, l=" << l << endl;
if (strcmp(buf,"hello\n"))
throw Exception("McThread socket read not as expected");
// for this test, expect EOF on second recv.
try {
l = socket->recv(buf,sizeof(buf));
}
catch(const EOFException& e) {
cerr << "requester EOF, closing socket" << endl;
socket->close();
delete socket;
return RUN_OK;
}
socket.close();
delete socket;
cerr << "requester no EOF, closing socket" << endl;
throw Exception("McThread socket read not as expected");
}
private:
McSocket<Socket>& client;
} cthread(client);
cthread.start();
Socket* socket = server.accept();
cerr << "server accepted, socket=" << hex << socket << endl;
socket->send("hello\n",7);
cerr << "server closing socket" << endl;
socket->close();
delete socket;
cerr << "joining client cthread" << endl;
cthread.join();
server.close();
client.close();
template<class SocketT>
nidas::util::McSocket< SocketT >::McSocket ( const McSocket< SocketT > &  x)

Copy constructor.

template<class SocketT >
nidas::util::McSocket< SocketT >::~McSocket ( )
virtual

Member Function Documentation

template<class SocketT >
SocketT * nidas::util::McSocket< SocketT >::accept ( Inet4PacketInfoX pktinfo)
throw (IOException
)

Like ServerSocket::accept(), this method will return a connected socket.

As with listen(), it registers with a McSocketListener to listen on the multicast address, then waits until a request is received with a matching request type and socket type. accept() will return with a pointer to a connected TCP Socket for a McSocket<Socket>, or to a DatagramSocket for a McSocket<DatagramSocket>, with a default destination address of the requesting host and port. The caller owns the pointer to the socket and is responsible for closing and deleting it when done.

References nidas::util::Cond::lock(), nidas::util::Cond::unlock(), VLOG, and nidas::util::Cond::wait().

Referenced by nidas::core::MultipleUDPSockets::connect(), nidas::core::McSocket::connect(), and nidas::core::McSocketUDP::connect().

template<class SocketT >
void nidas::util::McSocket< SocketT >::close ( )
throw (IOException
)
virtual
template<class SocketT >
SocketT * nidas::util::McSocket< SocketT >::connect ( Inet4PacketInfoX pktinfo)
throw (IOException
)

Do a request(), and then wait until a TCP connection is established, or a UDP datagram is received back.

Returns the pointer to the connected TCP Socket or the DatagramSocket. McSocket then owns the pointer to the socket and is responsible for closing and deleting it when done.

References nidas::util::Cond::lock(), nidas::util::Cond::unlock(), VLOG, and nidas::util::Cond::wait().

Referenced by nidas::core::McSocket::connect(), and nidas::core::McSocketUDP::connect().

template<class SocketT>
virtual void nidas::util::McSocket< SocketT >::connected ( SocketT *  ,
const Inet4PacketInfoX  
)
inlinevirtual

Virtual method that is called when a socket connection is established.

This must be implemented in derived classes if the user wants to implement an asynchronous, two-step connection using listen() instead of accept() for incoming requests or request() instead of connect() for outgoing requests.

Parameters
sockThe socket which is ready for I/O. McSocket then owns the pointer to the socket and is responsible for closing and deleting it when done.

Reimplemented in nidas::core::McSocket::MyMcSocket, and nidas::core::McSocketUDP::MyMcSocket.

template<class SocketT>
const Inet4SocketAddress& nidas::util::McSocket< SocketT >::getInet4McastSocketAddress ( ) const
inline

Get the multicast address for listening to requests.

Referenced by nidas::core::McSocket::getInet4McastSocketAddress(), and nidas::core::McSocketUDP::getInet4McastSocketAddress().

template<class SocketT>
Inet4NetworkInterface nidas::util::McSocket< SocketT >::getInterface ( ) const
inline
template<class SocketT >
std::list< Inet4NetworkInterface > nidas::util::McSocket< SocketT >::getInterfaces ( ) const
throw (IOException
)

Return all network interfaces on this system.

References nidas::util::MulticastSocket::getInterfaces(), and nidas::util::Inet4SocketAddress::getPort().

template<class SocketT>
int nidas::util::McSocket< SocketT >::getRequestType ( ) const
inline
template<class SocketT >
void nidas::util::McSocket< SocketT >::joinMulticaster ( )
private
template<class SocketT >
void nidas::util::McSocket< SocketT >::listen ( )
throw (IOException
)

Register with a McSocketListener to listen on the multicast address.

When a request is received on the socket port, with a matching request type and socket type, McSocketListener will either do a Socket::connect() to establish a TCP connection back to the requesting host and port if the socket type is SOCK_STREAM, or if the socket type is SOCK_DGRAM, will create a DatagramSocket with a default destination address of the requesting host and port. Once this has been done, McSocketListener will call the offer() method of this McSocket. offer() then calls the virtual connected() method, passing a pointer to the connected socket. Use either listen() or accept() to wait for a connection.

References nidas::util::McSocketListener::accept(), nidas::util::Inet4SocketAddress::toString(), and nidas::util::Exception::what().

template<class SocketT>
void nidas::util::McSocket< SocketT >::offer ( SocketT *  sock,
const Inet4PacketInfoX pktinfo 
)
private

How a McSocketListener passes back a connected TCP socket or DatagramSocket.

offer() calls the connected() virtual method. McSocket will own the pointer to the socket and is responsible for closing and deleting it when done.

Parameters
sockA pointer to a Socket. May be null, in which case err will be a non-zero errno that occured.
errIf sock is null, an errno.

References nidas::util::Cond::lock(), nidas::util::Cond::signal(), and nidas::util::Cond::unlock().

Referenced by nidas::util::McSocketListener::run().

template<class SocketT>
void nidas::util::McSocket< SocketT >::offer ( int  err)
private
template<class SocketT>
McSocket< SocketT > & nidas::util::McSocket< SocketT >::operator= ( const McSocket< SocketT > &  rhs)

Assignment operator.

template<class SocketT >
void nidas::util::McSocket< SocketT >::request ( )
throw (IOException
)

Start issuing requests for a connection by multicasting McSocketDatagrams.

When a response is received, either in the form of a TCP socket connection in the case of a socket type of SOCK_STREAM, or a datagram is received in the case of a socket type of SOCK_DGRAM, then the connected() method is called.

References nidas::util::Mutex::lock(), nidas::util::Thread::start(), nidas::util::Inet4SocketAddress::toString(), nidas::util::Mutex::unlock(), and nidas::util::Exception::what().

template<class SocketT>
void nidas::util::McSocket< SocketT >::setInet4McastSocketAddress ( const Inet4SocketAddress val)
inline

Set the multicast address for listening to requests.

Parameters
valMulticast address to listen for McSocketDatagrams.

Referenced by nidas::core::McSocket::setInet4McastSocketAddress(), and nidas::core::McSocketUDP::setInet4McastSocketAddress().

template<class SocketT>
void nidas::util::McSocket< SocketT >::setInterface ( Inet4NetworkInterface  iaddr)
inline

Set a specific interface for the multicasts.

If a request() or connect() is done, then requests will be sent on this interface. If an listen() or accept() is done, then an MulticastSocket::joinInterface() will be done on this interface to listen for incoming datagrams. If the interface is not set, or is left at the default of INADDR_ANY, then McSocket will send on or join all available interfaces capable of multicast, including the loopback interface.

template<class SocketT>
void nidas::util::McSocket< SocketT >::setRequestType ( int  val)
inline

Set the request type value.

This can be any number, agreed upon by the McSocket sending requests and the McSocket listening for requests.

Parameters
valRequest number

Referenced by nidas::core::requestXMLConfig(), nidas::core::McSocket::setRequestType(), and nidas::core::McSocketUDP::setRequestType().

Friends And Related Function Documentation

template<class SocketT>
friend class McSocketListener
friend

McSocketListener and McSocketMulticaster are friends that setup the socket connection and call the private offer() method.

template<class SocketT>
template<class SocketTT >
friend class McSocketMulticaster
friend

Member Data Documentation

template<class SocketT>
Cond nidas::util::McSocket< SocketT >::_connectCond
private
template<class SocketT>
Inet4NetworkInterface nidas::util::McSocket< SocketT >::_iface
private
template<class SocketT>
Inet4SocketAddress nidas::util::McSocket< SocketT >::_mcastAddr
private
template<class SocketT>
Thread* nidas::util::McSocket< SocketT >::_multicaster
private

The thread we start which multicasts for connections.

template<class SocketT>
Mutex nidas::util::McSocket< SocketT >::_multicaster_mutex
private
template<class SocketT>
Inet4PacketInfoX nidas::util::McSocket< SocketT >::_newpktinfo
private
template<class SocketT>
SocketT* nidas::util::McSocket< SocketT >::_newsocket
private
template<class SocketT>
int nidas::util::McSocket< SocketT >::_offerErrno
private
template<class SocketT>
int nidas::util::McSocket< SocketT >::_requestType
private
template<class SocketT>
bool nidas::util::McSocket< SocketT >::_socketOffered
private

The documentation for this class was generated from the following file: