mcast
Class MCastSocket

java.lang.Object
  extended by mcast.MCastSocket
Direct Known Subclasses:
TOMCastSocket

public class MCastSocket
extends java.lang.Object

MCastSocket: implements basic multicast transport. Is responsible for (a) the join protocol (via the lobby), and (b) effecting multicast (as repeated unicast).

The MCastSocket is multithreaded. When created, a thread is started that sits in a loop trying to read packets off the network, and putting them into a receive buffer. The client thread takes them out of that queue, by calling receive(). The client thread may also send packets.

Version:
$Id: MCastSocket.java,v 1.2 2009/01/13 05:36:20 zahorjan Exp $

Nested Class Summary
private  class MCastSocket.ReceiveHelper
          Helper class to implement receiving thread.
 
Field Summary
private static int BUFFER_SIZE
          Size of inComingPktBuf.
static int CLOSED
          Socket state All clients have left the group.
static int CONNECTED
          Socket state Socket is part of Mcast group (has heard a SERVER_CLIENT_HELLO and now knows who all is in the mcast group).
static int DRAINED
          Socket state There are no more packets in the received queue, and none on the network (i.e., there will never again be one available for receiving).
private  java.util.ArrayList<java.net.InetSocketAddress> groupMembers
          Addresses of mcast group members.
private  java.util.concurrent.ArrayBlockingQueue<MCastPacket> inComingPktBuf
          The queue of packets available for the client to receive().
private  java.net.InetSocketAddress lobbyAddress
          Location of the lobby (provider by creator of this object).
private  java.net.DatagramSocket mySocket
          The socket actually used to send and receive to/from the network.
private  int numDeparted
          Number of clients who have departed (i.e., promised they will send no more packets to the mcast group).
private  java.lang.Thread receiver
          The receive thread (takes packets off network and puts them in a packet buffer).
static int STARTING
          Socket state Initial state: not yet connected.
private  java.util.concurrent.Semaphore startSem
          Use to blocking user thread, in a call to join(), until receive thread notices that the mcast group has been joined.
private  int state
          Current state of the socket.
 
Constructor Summary
MCastSocket()
          Creates a new MCastSocket, obtaining an ephemeral (random) port number.
MCastSocket(int port)
          Creates a new MCastSocket with a specified port number.
 
Method Summary
 int getClientId(MCastPacket pkt)
          Returns a "client id" - an integer in the range 0..getMCastGroupSize()-1.
 int getMCastGroupSize()
          Returns the number of clients in the mcast group.
private  void init()
          Private function to initialize (called by constructors).
 void join(java.lang.String lobbyHost, int lobbyPort)
          Blocks the calling thread until the mcast group is joined.
 void leave()
          leave() is called by client when it's done sending.
 MCastPacket receive()
           
 void send(MCastPacket pkt)
          This is multicast send.
private  void unicastSendTo(MCastPacket pkt, java.net.InetSocketAddress addr)
          Private unicast send helper function.
private  void updateMCastClientList(java.lang.String clientList)
          Accept mcast client group message from lobby, parse it, can fill in group member data structure.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

STARTING

public static final int STARTING
Socket state Initial state: not yet connected.

See Also:
Constant Field Values

CONNECTED

public static final int CONNECTED
Socket state Socket is part of Mcast group (has heard a SERVER_CLIENT_HELLO and now knows who all is in the mcast group).

See Also:
Constant Field Values

CLOSED

public static final int CLOSED
Socket state All clients have left the group. There may still be packets in the received queue, but there are no more no the network.

See Also:
Constant Field Values

DRAINED

public static final int DRAINED
Socket state There are no more packets in the received queue, and none on the network (i.e., there will never again be one available for receiving).

See Also:
Constant Field Values

state

private int state
Current state of the socket.


startSem

private java.util.concurrent.Semaphore startSem
Use to blocking user thread, in a call to join(), until receive thread notices that the mcast group has been joined.


mySocket

private java.net.DatagramSocket mySocket
The socket actually used to send and receive to/from the network.


inComingPktBuf

private java.util.concurrent.ArrayBlockingQueue<MCastPacket> inComingPktBuf
The queue of packets available for the client to receive(). Note that it is synchronized: the client may be trying to pull something off of it at the same time the receive thread is trying to put something onto it.


BUFFER_SIZE

private static final int BUFFER_SIZE
Size of inComingPktBuf.

See Also:
Constant Field Values

receiver

private java.lang.Thread receiver
The receive thread (takes packets off network and puts them in a packet buffer).


lobbyAddress

private java.net.InetSocketAddress lobbyAddress
Location of the lobby (provider by creator of this object).


groupMembers

private java.util.ArrayList<java.net.InetSocketAddress> groupMembers
Addresses of mcast group members.


numDeparted

private int numDeparted
Number of clients who have departed (i.e., promised they will send no more packets to the mcast group).

Constructor Detail

MCastSocket

public MCastSocket()
            throws java.net.SocketException
Creates a new MCastSocket, obtaining an ephemeral (random) port number.

Throws:
java.net.SocketException

MCastSocket

public MCastSocket(int port)
            throws java.net.SocketException
Creates a new MCastSocket with a specified port number. Note that creation will fail if that port number is already in use on the host.

Parameters:
inbufSize - allows the caller to say how big the incoming packet buffer should be.
port - the port number
Throws:
java.net.SocketException
Method Detail

init

private void init()
Private function to initialize (called by constructors).


getClientId

public int getClientId(MCastPacket pkt)
Returns a "client id" - an integer in the range 0..getMCastGroupSize()-1. This id is guaranteed to be (a) unique, and (b) the same on on all clients.

The client id is not transmitted in the packet. The sender's host IP address and port are looked up in the list of mcast group clients, and the index in that list is the id.

Parameters:
pkt - The id of the sender of this packet is the value returned.

getMCastGroupSize

public int getMCastGroupSize()
Returns the number of clients in the mcast group.


join

public void join(java.lang.String lobbyHost,
                 int lobbyPort)
          throws java.net.UnknownHostException,
                 java.io.IOException
Blocks the calling thread until the mcast group is joined. join() must be called before any packets can be sent or received. join() effects the protocol that lets us discover who is in the mcast group. Causes a CLIENT_SERVER_HELLO to be sent to the lobby, and then waits for a SERVER_CLIENT_HELLO (which carries the addresses of the mcast group members). That response is actually seen by the receive thread, so there is some synchronization with it involved here.

Parameters:
lobbyHost - A string containing the lobby's host name or IP address.
lobbyPort - The lobby's port.
Throws:
java.net.UnknownHostException
java.io.IOException

leave

public void leave()
           throws java.io.IOException,
                  java.lang.InterruptedException
leave() is called by client when it's done sending. It causes a notification to be sent to all clients in the mcast group.

Throws:
java.io.IOException
java.lang.InterruptedException

send

public void send(MCastPacket pkt)
          throws java.io.IOException
This is multicast send. It is non-blocking (we don't (and can't) wait until the data arrives at the other end before returning to the caller).

Throws:
java.io.IOException

unicastSendTo

private void unicastSendTo(MCastPacket pkt,
                           java.net.InetSocketAddress addr)
                    throws java.io.IOException
Private unicast send helper function. (It doesn't have mcast semantics at all.) You name the single recipient, and off it goes. (Useful in implementing the lobby, as well as in talking with it, and in implementing multicast send().)

Throws:
java.io.IOException

receive

public MCastPacket receive()

updateMCastClientList

private void updateMCastClientList(java.lang.String clientList)
Accept mcast client group message from lobby, parse it, can fill in group member data structure.