Sequencer multicast protocol using Java
Principalele clase ale proiectului sunt:
SeqTest.java
package sequencer;
import java.awt.*;
import java.awt.event.*;
import java.io.PrintStream;
import java.util.EventObject;
// Referenced classes of package sequencer:
// Group
public class SeqTest extends Frame
implements Runnable, Group.MsgHandler, AdjustmentListener, ActionListener
{
public SeqTest(String host, String myName)
{
super("SeqTest");
returned = "Fred";
paused = false;
setSize(200, 200);
this.myName = myName;
slider = new Scrollbar(0, 0, 10, 0, 100);
slider.addAdjustmentListener(this);
rate = slider.getValue();
stopIt = new Button("Quit");
stopIt.addActionListener(this);
pauseIt = new Button("Pause/Continue");
pauseIt.addActionListener(this);
text = new TextField(80);
setLayout(new BorderLayout());
add("North", text);
add("East", stopIt);
add("West", pauseIt);
add("South", slider);
try
{
group = new Group(host, this, myName);
t = new Thread(this);
t.start();
}
catch(Exception ex)
{
System.out.println("Can't create group: " + ex);
}
}
public void adjustmentValueChanged(AdjustmentEvent e)
{
rate = slider.getValue();
slider.setValue(rate);
}
1
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == stopIt)
{
group.leave();
System.exit(1);
} else
if(e.getSource() == pauseIt)
paused = !paused;
}
public void run()
{
try
{
int i = 0;
do
{
do
if(rate <= 90)
try
{
Thread.sleep((90 - rate) * 10);
}
catch(Exception _ex) { }
while(paused);
group.send((new String(myName + ": " + i++)).getBytes());
} while(true);
}
catch(Exception ex)
{
System.out.println("Applet exception " + ex);
}
}
public synchronized void handle(int count, byte msg[])
{
text.setText(new String(msg, 0, count));
}
public static void main(String args[])
{
if(args.length < 2)
{
System.out.println("Usage: prog host clientName");
} else
{
SeqTest st = new SeqTest(args[0], args[1]);
st.show();
}
}
String returned;
Group group;
Thread t;
Scrollbar slider;
2
Button stopIt;
Button pauseIt;
TextField text;
int rate;
String myName;
boolean paused;
}
Group.java
package sequencer;
import java.io.*;
import java.net.*;
import java.rmi.Naming;
import java.util.Date;
// Referenced classes of package sequencer:
// SequencerJoinInfo, SequencerException, Sequencer, SequencerImpl
public class Group
implements Runnable
{
public class HeartBeater extends Thread
{
public void run()
{
do
try
{
do
Thread.sleep(period * 1000);
while((new Date()).getTime() - lastSendTime < (long)(period * 1000));
sequencer.heartbeat(myName, lastSequenceRecd);
}
catch(Exception _ex) { }
while(true);
}
int period;
public HeartBeater(int period)
{
this.period = period;
}
}
public interface MsgHandler
{
public abstract void handle(int i, byte abyte0[]);
}
public class GroupException extends Exception
{
3
public GroupException(String s)
{
super(s);
}
}
public Group(String host, MsgHandler handler, String name)
throws GroupException
{
lastSequenceRecd = -1L;
lastSequenceSent = -1L;
try
{
String fred[] = Naming.list("//mpc2/");
for(int i = 0; i < fred.length; i++)
System.out.println(String.valueOf(fred[i]));
myAddr = InetAddress.getLocalHost();
sequencer = (Sequencer)Naming.lookup("//" + host + "/TKSequencer");
myName = name + myAddr;
SequencerJoinInfo joinInfo = sequencer.join(myName);
groupAddr = joinInfo.addr;
lastSequenceRecd = joinInfo.sequence;
System.out.println("ip of group: " + groupAddr);
socket = new MulticastSocket(10000);
socket.joinGroup(groupAddr);
this.handler = handler;
t = new Thread(this);
t.start();
heartBeater = new HeartBeater(5);
heartBeater.start();
}
catch(SequencerException ex)
{
System.out.println("Couldn't create group " + ex);
throw new GroupException(String.valueOf(ex));
}
catch(Exception ex)
{
System.out.println("Couldn't create group " + ex);
throw new GroupException("Couldn't join to sequencer");
}
}
public void send(byte msg[])
throws GroupException
{
if(socket != null)
try
{
sequencer.send(myName, ++lastSequenceSent, lastSequenceRecd, msg);
lastSendTime = (new Date()).getTime();
}
catch(Exception ex)
{
System.out.println("couldn't contact sequencer " + ex);
4
throw new GroupException("Couldn't send to sequencer");
}
else
throw new GroupException("Group not joined");
}
public void leave()
{
if(socket != null)
try
{
socket.leaveGroup(groupAddr);
sequencer.leave(myName);
}
catch(Exception ex)
{
System.out.println("couldn't leave group " + ex);
}
}
public void run()
{
try
{
while(true)
{
byte buf[] = new byte[10240];
DatagramPacket dgram = new DatagramPacket(buf, buf.length);
socket.receive(dgram);
ByteArrayInputStream bstream = new ByteArrayInputStream(buf, 0, dgram.getLength());
DataInputStream dstream = new DataInputStream(bstream);
long gotSequence = dstream.readLong();
int count = dstream.read(buf);
long wantSeq = lastSequenceRecd + 1L;
if(lastSequenceRecd >= 0L && wantSeq < gotSequence)
{
for(long getSeq = wantSeq; getSeq < gotSequence; getSeq++)
{
byte bufExtra[] = sequencer.getMissing(getSeq);
int countExtra = bufExtra.length;
System.out.println("Group: fetch missing " + getSeq);
handler.handle(countExtra, bufExtra);
}
}
lastSequenceRecd = gotSequence;
handler.handle(count, buf);
}
}
catch(Exception ex)
{
System.out.println("bad in run " + ex);
}
}
Thread t;
Thread heartBeater;
5
Sequencer sequencer;
MulticastSocket socket;
MsgHandler handler;
long lastSequenceRecd;
long lastSequenceSent;
InetAddress groupAddr;
InetAddress myAddr;
String myName;
long lastSendTime;
}
Sequencer.java
package sequencer;
import java.rmi.Remote;
import java.rmi.RemoteException;
// Referenced classes of package sequencer:
// SequencerException, SequencerJoinInfo
public interface Sequencer
extends Remote
{
public abstract SequencerJoinInfo join(String s)
throws RemoteException, SequencerException;
public abstract void send(String s, long l, long l1, byte abyte0[])
throws RemoteException;
public abstract void leave(String s)
throws RemoteException;
public abstract byte[] getMissing(long l)
throws RemoteException, SequencerException;
public abstract void heartbeat(String s, long l)
throws RemoteException;
}
SequencerImpl.java
package sequencer;
import java.io.*;
import java.net.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.util.Vector;
// Referenced classes of package sequencer:
// SequencerJoinInfo, History, SequencerException, Sequencer
public class SequencerImpl extends UnicastRemoteObject
implements Sequencer
{
6
public SequencerImpl(String name)
throws RemoteException
{
this.name = name;
try
{
history = new History();
mySenders = new Vector();
socket = new MulticastSocket();
groupAddr = InetAddress.getByName("228.5.6.7");
// groupAddr = InetAddress.getByName("172.16.4.124");
}
catch(Exception ex)
{
System.out.println("Couldn't initialise seq: " + ex);
}
}
public synchronized SequencerJoinInfo join(String senderName)
throws RemoteException, SequencerException
{
if(mySenders.contains(senderName))
{
throw new SequencerException(senderName + " not unique");
} else
{
mySenders.addElement(senderName);
history.noteReceived(senderName, sequence);
return new SequencerJoinInfo(groupAddr, sequence);
}
}
public synchronized void send(String sender, long id, long lastRecd, byte msg[])
throws RemoteException
{
try
{
ByteArrayOutputStream bstream = new ByteArrayOutputStream(10240);
DataOutputStream dstream = new DataOutputStream(bstream);
dstream.writeLong(++sequence);
dstream.write(msg, 0, msg.length);
socket.send(new DatagramPacket(bstream.toByteArray(), bstream.size(), groupAddr, 10000));
}
catch(Exception ex)
{
System.out.println("problem sending by sequ " + ex);
}
history.noteReceived(sender, lastRecd);
history.addMsg(sender, sequence, msg);
}
public byte[] getMissing(long sequence)
throws RemoteException, SequencerException
{
byte found[] = history.getMsg(sequence);
if(found != null)
{
7
System.out.println("Sequencer supplies missing " + sequence);
return found;
} else
{
System.out.println("Sequencer couldn't find missing " + sequence);
throw new SequencerException("Couldn't find missing " + sequence);
}
}
public synchronized void heartbeat(String sender, long lastRecd)
{
System.out.println(sender + " HEARTBEAT: " + lastRecd);
history.noteReceived(sender, lastRecd);
}
public synchronized void leave(String senderName)
throws RemoteException
{
mySenders.removeElement(senderName);
history.eraseSender(senderName);
}
public static void main(String args[])
{
System.setSecurityManager(new RMISecurityManager());
try
{
SequencerImpl impl = new SequencerImpl("TKSequencer");
Naming.rebind("/TKSequencer", impl);
System.out.println("Bound OK");
}
catch(Exception ex)
{
System.out.println("Sequencer server failed: " + ex);
}
}
private int sequence;
private String name;
MulticastSocket socket;
public static final int MAX_MSG_LENGTH = 10240;
private static final String ipAddr = "228.5.6.7";
// private static final String ipAddr = "172.16.4.124";
public static final int GROUP_PORT = 10000;
InetAddress groupAddr;
History history;
Vector mySenders;
}
History.java
package sequencer;
import java.io.PrintStream;
import java.util.Enumeration;
import java.util.Hashtable;
8
public class History extends Hashtable
{
public History()
{
historyCleanedTo = -1L;
senders = new Hashtable();
}
public synchronized void noteReceived(String sender, long recvd)
{
senders.put(sender, new Long(recvd));
}
public synchronized void addMsg(String sender, long sequence, byte msg[])
{
if(msg != null)
put(new Long(sequence), msg);
if(size() > 1024)
{
System.out.println("CLEAN HISTORY; size: " + size());
long min = 0x7fffffffffffffffL;
for(Enumeration enum1 = senders.keys(); enum1.hasMoreElements();)
{
String sent = (String)enum1.nextElement();
Long got = (Long)senders.get(sent);
long have = got.longValue();
System.out.println(sent + " has received " + have);
if(have < min)
min = have;
}
System.out.println("clean from " + (historyCleanedTo + 1L) + " to " + min);
for(long s = historyCleanedTo + 1L; s <= min; s++)
{
remove(new Long(s));
historyCleanedTo = s;
}
System.out.println("CLEANED HISTORY; size is now " + size());
}
}
public byte[] getMsg(long sequence)
{
return (byte[])get(new Long(sequence));
}
public synchronized void eraseSender(String sender)
{
senders.remove(sender);
}
private Hashtable senders;
public static final int MAX_HISTORY = 1024;
long historyCleanedTo;
}
9
Alte clase sunt:
SequencerJoinInfo.java
package sequencer;
import java.io.Serializable;
import java.net.InetAddress;
public class SequencerJoinInfo
implements Serializable
{
public SequencerJoinInfo(InetAddress addr, long sequence)
{
this.addr = addr;
this.sequence = sequence;
}
public InetAddress addr;
public long sequence;
}
SequencerImpl_Skel.java
package sequencer;
import java.io.*;
import java.rmi.*;
import java.rmi.server.*;
// Referenced classes of package sequencer:
// SequencerImpl
public final class SequencerImpl_Skel
implements Skeleton
{
public Operation[] getOperations()
{
return operations;
}
public void dispatch(Remote remote, RemoteCall remotecall, int i, long l)
throws RemoteException, Exception
{
if(l != 0x46fe5f6f059e0674L)
throw new SkeletonMismatchException("Hash mismatch");
SequencerImpl sequencerimpl = (SequencerImpl)remote;
switch(i)
{
case 0: // '\0'
long l1;
try
{
ObjectInput objectinput2 = remotecall.getInputStream();
l1 = objectinput2.readLong();
}
catch(IOException ioexception6)
10
{
throw new UnmarshalException("Error unmarshaling arguments", ioexception6);
}
finally
{
remotecall.releaseInputStream();
}
byte abyte0[] = sequencerimpl.getMissing(l1);
try
{
ObjectOutput objectoutput1 = remotecall.getResultStream(true);
objectoutput1.writeObject(abyte0);
return;
}
catch(IOException ioexception2)
{
throw new MarshalException("Error marshaling return", ioexception2);
}
case 1: // '\001'
String s;
long l2;
try
{
ObjectInput objectinput3 = remotecall.getInputStream();
s = (String)objectinput3.readObject();
l2 = objectinput3.readLong();
}
catch(IOException ioexception7)
{
throw new UnmarshalException("Error unmarshaling arguments", ioexception7);
}
finally
{
remotecall.releaseInputStream();
}
sequencerimpl.heartbeat(s, l2);
try
{
remotecall.getResultStream(true);
return;
}
catch(IOException ioexception3)
{
throw new MarshalException("Error marshaling return", ioexception3);
}
case 2: // '\002'
String s1;
try
{
ObjectInput objectinput = remotecall.getInputStream();
s1 = (String)objectinput.readObject();
}
catch(IOException ioexception4)
{
throw new UnmarshalException("Error unmarshaling arguments", ioexception4);
11
}
finally
{
remotecall.releaseInputStream();
}
SequencerJoinInfo sequencerjoininfo = sequencerimpl.join(s1);
try
{
ObjectOutput objectoutput = remotecall.getResultStream(true);
objectoutput.writeObject(sequencerjoininfo);
return;
}
catch(IOException ioexception1)
{
throw new MarshalException("Error marshaling return", ioexception1);
}
case 3: // '\003'
String s2;
try
{
ObjectInput objectinput1 = remotecall.getInputStream();
s2 = (String)objectinput1.readObject();
}
catch(IOException ioexception5)
{
throw new UnmarshalException("Error unmarshaling arguments", ioexception5);
}
finally
{
remotecall.releaseInputStream();
}
sequencerimpl.leave(s2);
try
{
remotecall.getResultStream(true);
return;
}
catch(IOException ioexception)
{
throw new MarshalException("Error marshaling return", ioexception);
}
case 4: // '\004'
String s3;
long l3;
long l4;
byte abyte1[];
try
{
ObjectInput objectinput4 = remotecall.getInputStream();
s3 = (String)objectinput4.readObject();
l3 = objectinput4.readLong();
l4 = objectinput4.readLong();
abyte1 = (byte[])objectinput4.readObject();
}
catch(IOException ioexception9)
12
{
throw new UnmarshalException("Error unmarshaling arguments", ioexception9);
}
finally
{
remotecall.releaseInputStream();
}
sequencerimpl.send(s3, l3, l4, abyte1);
try
{
remotecall.getResultStream(true);
return;
}
catch(IOException ioexception8)
{
throw new MarshalException("Error marshaling return", ioexception8);
}
}
throw new RemoteException("Method number out of range");
}
public SequencerImpl_Skel()
{
}
private static Operation operations[] = {
new Operation("byte getMissing(long)[]"), new Operation("void heartbeat(java.lang.String, long)"),
new Operation("sequencer.SequencerJoinInfo join(java.lang.String)"), new Operation("void
leave(java.lang.String)"), new Operation("void send(java.lang.String, long, long, byte[])")
};
private static final long interfaceHash = 0x46fe5f6f059e0674L;
SequencerImpl_Stub.java
package sequencer;
import java.io.*;
import java.rmi.*;
import java.rmi.server.*;
// Referenced classes of package sequencer:
// Sequencer, SequencerException, SequencerJoinInfo
public final class SequencerImpl_Stub extends RemoteStub
implements Sequencer, Remote
{
public SequencerImpl_Stub()
{
}
public SequencerImpl_Stub(RemoteRef remoteref)
{
super(remoteref);
}
13
public byte[] getMissing(long l)
throws RemoteException, SequencerException
{
int i = 0;
RemoteRef remoteref = super.ref;
RemoteCall remotecall = remoteref.newCall(this, operations, i, 0x46fe5f6f059e0674L);
try
{
ObjectOutput objectoutput = remotecall.getOutputStream();
objectoutput.writeLong(l);
}
catch(IOException ioexception)
{
throw new MarshalException("Error marshaling arguments", ioexception);
}
try
{
remoteref.invoke(remotecall);
}
catch(RemoteException remoteexception)
{
throw remoteexception;
}
catch(SequencerException sequencerexception)
{
throw sequencerexception;
}
catch(Exception exception)
{
throw new UnexpectedException("Unexpected exception", exception);
}
byte abyte0[];
try
{
ObjectInput objectinput = remotecall.getInputStream();
abyte0 = (byte[])objectinput.readObject();
}
catch(IOException ioexception1)
{
throw new UnmarshalException("Error unmarshaling return", ioexception1);
}
catch(ClassNotFoundException classnotfoundexception)
{
throw new UnmarshalException("Return value class not found", classnotfoundexception);
}
catch(Exception exception2)
{
throw new UnexpectedException("Unexpected exception", exception2);
}
finally
{
remoteref.done(remotecall);
}
return abyte0;
}
public void heartbeat(String s, long l)
14
throws RemoteException
{
int i = 1;
RemoteRef remoteref = super.ref;
RemoteCall remotecall = remoteref.newCall(this, operations, i, 0x46fe5f6f059e0674L);
try
{
ObjectOutput objectoutput = remotecall.getOutputStream();
objectoutput.writeObject(s);
objectoutput.writeLong(l);
}
catch(IOException ioexception)
{
throw new MarshalException("Error marshaling arguments", ioexception);
}
try
{
remoteref.invoke(remotecall);
}
catch(RemoteException remoteexception)
{
throw remoteexception;
}
catch(Exception exception)
{
throw new UnexpectedException("Unexpected exception", exception);
}
remoteref.done(remotecall);
}
public SequencerJoinInfo join(String s)
throws RemoteException, SequencerException
{
byte byte0 = 2;
RemoteRef remoteref = super.ref;
RemoteCall remotecall = remoteref.newCall(this, operations, byte0, 0x46fe5f6f059e0674L);
try
{
ObjectOutput objectoutput = remotecall.getOutputStream();
objectoutput.writeObject(s);
}
catch(IOException ioexception)
{
throw new MarshalException("Error marshaling arguments", ioexception);
}
try
{
remoteref.invoke(remotecall);
}
catch(RemoteException remoteexception)
{
throw remoteexception;
}
catch(SequencerException sequencerexception)
{
throw sequencerexception;
}
15
catch(Exception exception)
{
throw new UnexpectedException("Unexpected exception", exception);
}
SequencerJoinInfo sequencerjoininfo;
try
{
ObjectInput objectinput = remotecall.getInputStream();
sequencerjoininfo = (SequencerJoinInfo)objectinput.readObject();
}
catch(IOException ioexception1)
{
throw new UnmarshalException("Error unmarshaling return", ioexception1);
}
catch(ClassNotFoundException classnotfoundexception)
{
throw new UnmarshalException("Return value class not found", classnotfoundexception);
}
catch(Exception exception2)
{
throw new UnexpectedException("Unexpected exception", exception2);
}
finally
{
remoteref.done(remotecall);
}
return sequencerjoininfo;
}
public void leave(String s)
throws RemoteException
{
byte byte0 = 3;
RemoteRef remoteref = super.ref;
RemoteCall remotecall = remoteref.newCall(this, operations, byte0, 0x46fe5f6f059e0674L);
try
{
ObjectOutput objectoutput = remotecall.getOutputStream();
objectoutput.writeObject(s);
}
catch(IOException ioexception)
{
throw new MarshalException("Error marshaling arguments", ioexception);
}
try
{
remoteref.invoke(remotecall);
}
catch(RemoteException remoteexception)
{
throw remoteexception;
}
catch(Exception exception)
{
throw new UnexpectedException("Unexpected exception", exception);
}
remoteref.done(remotecall);
16
}
public void send(String s, long l, long l1, byte abyte0[])
throws RemoteException
{
byte byte0 = 4;
RemoteRef remoteref = super.ref;
RemoteCall remotecall = remoteref.newCall(this, operations, byte0, 0x46fe5f6f059e0674L);
try
{
ObjectOutput objectoutput = remotecall.getOutputStream();
objectoutput.writeObject(s);
objectoutput.writeLong(l);
objectoutput.writeLong(l1);
objectoutput.writeObject(abyte0);
}
catch(IOException ioexception)
{
throw new MarshalException("Error marshaling arguments", ioexception);
}
try
{
remoteref.invoke(remotecall);
}
catch(RemoteException remoteexception)
{
throw remoteexception;
}
catch(Exception exception)
{
throw new UnexpectedException("Unexpected exception", exception);
}
remoteref.done(remotecall);
}
private static Operation operations[] = {
new Operation("byte getMissing(long)[]"), new Operation("void heartbeat(java.lang.String, long)"),
new Operation("sequencer.SequencerJoinInfo join(java.lang.String)"), new Operation("void
leave(java.lang.String)"), new Operation("void send(java.lang.String, long, long, byte[])")
};
private static final long interfaceHash = 0x46fe5f6f059e0674L;
17