//#
//# Multicast Class based on Java's java.net.MulticastSocket
//# $Revision: 1.1 $
//# Copyright 2004 by Eric Y. Theriault
//# All Rights Reserved.
//# http://www.eyt.ca/CORBA
//#
#ifndef _EYT_MULTICASTSOCKET_H
#define _EYT_MULTICASTSOCKET_H

//#
//# Required Classes
//#
#ifndef _EYT_STRING
#include <string>
#define _EYT_STRING
#endif
#ifdef _WIN32
#ifndef _EYT_WINSOCK2_H
#include <winsock2.h>
#define _EYT_WINSOCK2_H
#endif
#ifndef _EYT_WINDOWS_H
#include <windows.h>
#define _EYT_WINDOWS_H
#endif
#ifndef _EYT_WS2TCPIP_H
#include <ws2tcpip.h>
#define _EYT_WS2TCPIP_H
#endif
#else
#ifndef _EYT_NETINET_IN_H
#include <netinet/in.h>
#define _EYT_NETINET_IN_H
#endif
#endif

//#
//# Forward Declarations
//#
struct sockaddr_in;

//
// <summary> Implements a Multicast Socket Wrapper </summary>
//
// Based on java.net.MulticastSocket, implements some required functions
// for this CORBA project.  More information regarding this can be
// found in Unix Network Programming: Volume 1.
//
// This class will raise std::exception on any failure that occurs.
//
class MulticastSocket {
#ifndef _WIN32
    typedef int SOCKET;
#endif

private:
	// Port to bind
	int port_;

	// Timeout
	int timeout_;

	// Socket
	SOCKET socket_;

public:
	//
	// Constructs a socket on the specified port.
	//
	// Port is the UDP port to multicast on.
	// Bind denotes whether to bind or not; only the server should
	// bind.
	//
	explicit MulticastSocket( int port, bool bind = false );

	//
	// Destructor
	//
	~MulticastSocket();

	//
	// Join a multicast group.
	//
	// The ipv4Address is a multicast group address, such as
	// 224.0.0.1.
	// The ifaceAddress is the address of the interface to multicast
	// on to; a null pointer will use the default route.
	//
	void joinGroup(
                       const char *ipv4Address,
                       const char *ifaceAddress = 0
                      );


	//
	// Send a packet.
	//
	// The ipv4Address specifies either a multicast or unicast
	// IP address to send the data to.
	// The packet is some C-string to send.
	//
	// <group>
	void send(
                  const char *ipv4Address,
                  const char *packet
                 );
	void send(
                  const struct sockaddr_in &address,
                  const char *packet
                 );
	// </group>

	//
	// Set the timeout value.
	//
	// timeout is in milliseconds; a 0 value disables the timeout.
	// negative values are undefined.
	//
	void setSoTimeout( int timeout );

	//
	// Receives a packet.
	//
	// Returns the std::string and address that was received.
	//
	std::string receive( struct sockaddr_in &address );
};

#endif

