demo ready now

tmk29 [2002-12-12 22:54:30]
demo ready now
Filename
meet-j/server/clocks/LamportClock.java
meet-j/server/clocks/MEETClock.java
meet-j/server/clocks/NTPTimeStamp.java
meet-j/server/clocks/SNTPClock.java
diff --git a/meet-j/server/clocks/LamportClock.java b/meet-j/server/clocks/LamportClock.java
index 657a558..64a8289 100644
--- a/meet-j/server/clocks/LamportClock.java
+++ b/meet-j/server/clocks/LamportClock.java
@@ -4,53 +4,144 @@
  * Created on October 31, 2002, 1:04 PM
  */

-package psl.meet.server.clocks;
-
 import java.util.Timer;
 import java.util.TimerTask;
+import java.lang.Math;

 /**
  *
  * @author  mkuba
  */
-public class LamportClock {
+public class LamportClock implements MEETClock {

     private long clock;
+    private int INTERVAL;

-    /** Creates a new instance of LamportClock */
+    /**
+     * Creates a new instance of LamportClock
+     */
     public LamportClock() {
         clock = 0;
+	INTERVAL = 5;

         Timer t = new Timer();

-        // every second
-        t.scheduleAtFixedRate(new updateTask(),0,1000);
+        // update the Lamport clock by default every 5 ms
+        t.scheduleAtFixedRate(new updateTask(),0,INTERVAL);

     }
+
+    /**
+     * constructor with user-defined interval, in ms
+     */
+    public LamportClock(int i) {
+	clock = 0;
+	INTERVAL = i;
+
+	Timer t = new Timer();
+	t.scheduleAtFixedRate(new updateTask(),0,INTERVAL);
+    }
+
+    /**
+     * return Lamport timestamp
+     * this is from the MEETClock interface
+     */
+    public long getTime() {
+	return getLamport();
+    }
+
+    /**
+     * return clock name
+     * this is from the MEETClock interface
+     */
+    public String getClockName() {
+	return "LamportClock";
+    }

+    /**
+     * return Lamport timestamp
+     */
     public long getLamport() {
         return clock;
     }

-
+
+    /**
+     * synchronize the Lamport clock
+     */
     public void setLamport(long time) {
         if (time > clock) {
             clock = time + 1;
         } else {
         }
     }
-
+
+    /**
+     * for the Timer class
+     */
     class updateTask extends TimerTask {
         public void run() {
             clock++;
             //DEBUG
-            System.out.println("Clock = " + clock);
+            //System.out.println("Clock = " + clock);
         }
     }
-
-    public static void main(String args[]) {
-        LamportClock l1 = new LamportClock();
-        LamportClock l2 = new LamportClock();
+
+
+    /**
+     * test program
+     */
+    public static void main(String args[]) throws Exception {
+
+	// if invalid # of arguments
+	if (args.length < 2) {
+	    System.out.println("Usage: java LamportClock <tick size> <network multiplier>");
+	    System.out.println("\tWhere <tick size> is the tick size of the Lamport Clock");
+	    System.out.println("\tand <network multiplier> is how slow the network is compared to the tick size (i.e. 5 times slower, etc)");
+	    System.exit(0);
+	}
+
+	// set up the interval and network delay
+	int interval = Integer.parseInt(args[0]);
+	float multiplier = Float.parseFloat(args[1]);
+
+	// clock 1
+        LamportClock l1 = new LamportClock(interval);
+	l1.setLamport(2000);
+
+	// clock 2
+        LamportClock l2 = new LamportClock(interval);
+	l2.setLamport(1000);
+
+	// clock 3
+        LamportClock l3 = new LamportClock(interval);
+
+	System.out.println("Larry\tCurly\tMoe");
+	System.out.println(l1.getLamport() + "\t" + l2.getLamport() + "\t" + l3.getLamport());
+
+	// keep updating the clocks, simulating a network
+	while (true) {
+	    Thread.sleep(Math.min(interval*50,1000));
+
+	    long x = l2.getLamport();
+	    Thread.sleep((int)(multiplier*interval));
+	    l1.setLamport(x);
+	    l2.setLamport(x);
+
+	    long y = l1.getLamport();
+	    Thread.sleep((int)(multiplier*interval));
+	    l2.setLamport(y);
+	    l3.setLamport(y);
+
+	    long z = l3.getLamport();
+	    Thread.sleep((int)(multiplier * interval));
+	    l1.setLamport(z);
+	    l2.setLamport(z);
+
+	    // print clock information
+	    System.out.println(l1.getLamport() + "\t" + l2.getLamport() + "\t" + l3.getLamport());
+
+	}
     }

 }
diff --git a/meet-j/server/clocks/MEETClock.java b/meet-j/server/clocks/MEETClock.java
new file mode 100644
index 0000000..d8bc651
--- /dev/null
+++ b/meet-j/server/clocks/MEETClock.java
@@ -0,0 +1,7 @@
+public interface MEETClock {
+
+    public String getClockName();
+
+    public long getTime();
+
+}
diff --git a/meet-j/server/clocks/NTPTimeStamp.java b/meet-j/server/clocks/NTPTimeStamp.java
index fd0d3bf..adb4172 100644
--- a/meet-j/server/clocks/NTPTimeStamp.java
+++ b/meet-j/server/clocks/NTPTimeStamp.java
@@ -17,21 +17,18 @@ import java.lang.Math;
 public class NTPTimeStamp {


-    // milliseconds since Jan 1 1900 00:00:00 UT
-    private long milli;
-
-    // seconds since Epoch
+    // seconds since Jan 1 1900 00:00:00 UT
     private long secs;

     // fraction of a second
     private float fracsecs;

     // system offset, seconds between 1970 and 1900
-    //private long OFFSET = 2208970800;
-    //private final long OFFSET = 0;
-
     private final BigInteger OFFSET = new BigInteger("2208970800");

+    /**
+     * create a new NTPTimeStamp
+     */
     public NTPTimeStamp() {
 	Date now = new Date();
 	secs = (long)(now.getTime() / 1000);
@@ -42,6 +39,11 @@ public class NTPTimeStamp {
 	fracsecs = foo / 1000;
     }

+
+    /**
+     * create a new NTPTimeStamp, where
+     * system clock is set to a non-UT timezone
+     */
     public NTPTimeStamp(int tz) {
 	Date now = new Date();
 	secs = (long)(now.getTime() / 1000);
@@ -55,13 +57,19 @@ public class NTPTimeStamp {
     }


-    // time == milliseconds since 1970
+    /**
+     * create an NTPTimeStamp for a given timestamp and timezone
+     * time == milliseconds since 1970
+     */
     public NTPTimeStamp(long time, int tz) {
 	secs = (long)(time / 1000) + OFFSET.longValue() - (tz*3600);
 	float foo = (float)(time % 1000);
 	fracsecs = foo / 1000;
     }

+    /**
+     * create an NTPTimeStamp for a given Date object and timezone
+     */
     public NTPTimeStamp(Date now, int tz) {
 	long time = now.getTime();
 	secs = (long)(time / 1000) + OFFSET.longValue() - (tz*3600);
@@ -71,6 +79,9 @@ public class NTPTimeStamp {
     }


+    /**
+     * create an NTPTimeStamp given 8 bytes in the NTP Timestamp format
+     */
     public NTPTimeStamp(byte[] b) {

 	// parse the bytes to get a long
@@ -95,14 +106,25 @@ public class NTPTimeStamp {
 	fracsecs = bytesToFloat(d);
     }

+    /**
+     * return number of seconds since 1900
+     */
     public long getSecs() {
 	return secs;
     }

+
+    /**
+     * return fraction of second
+     */
     public float getFracSecs() {
 	return fracsecs;
     }

+
+    /**
+     * return milliseconds since 1900
+     */
     public long getLong() {
 	long foo = (long)(1000 * fracsecs);

@@ -112,11 +134,11 @@ public class NTPTimeStamp {
 	return (1000*secs + foo);
     }

-
-    // take the seconds, return
-    // 8 bytes in NTP Timestamp format
-    // for use in Tx and Rx of NTP info
-
+    /**
+     * take the seconds, return
+     * 8 bytes in NTP Timestamp format
+     * for use in Tx and Rx of NTP info
+     */
     public byte[] getBytes() {

 	BigInteger bar = BigInteger.valueOf(secs);
@@ -144,11 +166,11 @@ public class NTPTimeStamp {
     }


-
-    // Returns a bitset containing the values in bytes.
-    // The byte-ordering of bytes must be big-endian which means
-    // the most significant bit is in element 0.
-
+    /**
+     * Returns a bitset containing the values in bytes.
+     * The byte-ordering of bytes must be big-endian which means
+     * the most significant bit is in element 0.
+     */
     public static BitSet fromByteArray(byte[] bytes) {
 	BitSet bits = new BitSet(32);

@@ -164,7 +186,9 @@ public class NTPTimeStamp {
     }


-
+    /**
+     * BitSet -> ByteArray
+     */
     private static byte[] toByteArray(BitSet bits) {
         byte[] bytes = new byte[4];

@@ -180,7 +204,9 @@ public class NTPTimeStamp {
     }


-
+    /**
+     * DEBUG method
+     */
     private static void printByteArray(byte[] b) {
         for (int i=0; i<b.length; i++) {
             System.out.print(b[i] + " ");
@@ -189,6 +215,9 @@ public class NTPTimeStamp {
     }


+    /**
+     * bytes to a floating point
+     */
     private static float bytesToFloat(byte[] b) {

 	float output = 0;
@@ -205,7 +234,9 @@ public class NTPTimeStamp {

     }

-
+    /**
+     * floating point to fixed point
+     */
     private static BitSet floatToFixedPoint(float foo) {

         BitSet output = new BitSet(32);
@@ -226,7 +257,9 @@ public class NTPTimeStamp {

     }

-
+    /**
+     * test program
+     */
     public static void main(String args[]) throws Exception {

 	Date nowDate = new Date();
diff --git a/meet-j/server/clocks/SNTPClock.java b/meet-j/server/clocks/SNTPClock.java
index 8cec404..a114124 100644
--- a/meet-j/server/clocks/SNTPClock.java
+++ b/meet-j/server/clocks/SNTPClock.java
@@ -17,7 +17,10 @@ import java.util.BitSet;
  *
  * @author  mkuba
  */
-public class SNTPClock {
+public class SNTPClock implements MEETClock {
+
+    // print debug statements
+    final boolean DEBUG = false;

     // multicast or unicast client, unused for now
     boolean multiCastMode;
@@ -31,13 +34,16 @@ public class SNTPClock {
     private long delay;

     // automatically update clock at certain intervals
+    // unused for now
     private long updateInterval;

     // NTP Server to use
     private String server;
     private int port;

-    private int timezone = -5;
+    // offset from UT, in hours
+    private int timezone;
+

     /** Creates a new instance of SNTPClock */
     public SNTPClock() {
@@ -49,6 +55,9 @@ public class SNTPClock {
 	offset = 0;
     }

+    /**
+     * creates a new SNTPClock
+     */
     public SNTPClock(String srvr, int p, int tz, long updateint) {
 	server = srvr;
 	port = p;
@@ -58,38 +67,72 @@ public class SNTPClock {
 	offset = 0;
     }

+    /**
+     * set what timezone we are in
+     */
     public void setTimezone(int tz) {
 	timezone = tz;
     }

+    /**
+     * set which NTP server to use
+     */
     public void setSource(String srvr, int p) {
 	server = srvr;
 	port = p;
     }

+    /**
+     * set the update interval
+     */
     public void setUpdateInterval(long ui) {
 	updateInterval = ui;
     }

+    /**
+     * return the clock name
+     * from MEETClock interface
+     */
+    public String getClockName() {
+	return "SNTPClock";
+    }
+
+    /**
+     * return # of milliseconds since Jan 1 1900, 00:00:00 UT
+     */
     public long getTime() {
 	NTPTimeStamp now = new NTPTimeStamp(timezone);
 	return now.getLong() + offset;
     }

+    /**
+     * get the offset from the reference clock
+     * in number of milliseconds
+     */
     public long getOffset() {
 	return offset;
     }

+    /**
+     * get the calculated network delay
+     */
     public long getDelay() {
 	return delay;
     }

-
+    /**
+     * synchronize with NTP server
+     */
     public void sync() throws Exception {
 	byte[] b = this.createSNTPRequest();
 	this.send(b);
     }
-
+
+
+    /**
+     * send bytes to NTP Server
+     *
+     */
     public void send(byte[] data) throws Exception {

         // create socket to server
@@ -103,13 +146,13 @@ public class SNTPClock {


         // send packet
-        System.out.println("Attempting to send packet to " + socket.getInetAddress() + " (" + socket.getPort()  + ")\n");
-        socket.send(packet);
-        System.out.println("Packet sent\n");
-
+        if (DEBUG) System.out.println("Attempting to send packet to " + socket.getInetAddress() + " (" + socket.getPort()  + ")\n");

+        socket.send(packet);

+        if (DEBUG) System.out.println("Packet sent\n");

+	// create receiving packet
 	byte[] rx = new byte[48];
 	packet = new DatagramPacket(rx,48);

@@ -117,11 +160,17 @@ public class SNTPClock {
 	//socket.close();


-        //System.out.println("waiting for packet\n");
+	// receive packet
         socket.receive(packet);

+	// calculate timestamp for time packet was received
+	// this is occasionally not correct, probably because
+	// of java instruction reordering
         NTPTimeStamp T4 = new NTPTimeStamp(timezone);

+
+	// parse Timestamps from received packet
+
 	byte[] t1 = new byte[8];
 	for (int i=0; i<8; i++) {
 	    t1[i] = rx[24+i];
@@ -140,6 +189,7 @@ public class SNTPClock {
 	}
 	NTPTimeStamp T3 = new NTPTimeStamp(t3);

+
 	// delay and offset, as defined in RFC 2030

 	delay = ( (T4.getLong() - T1.getLong()) - (T2.getLong() - T3.getLong()) );
@@ -149,20 +199,25 @@ public class SNTPClock {


 	//DEBUG
-	System.out.println("T1 = " + T1.getLong());
-	System.out.println("T2 = " + T2.getLong());
-	System.out.println("T3 = " + T3.getLong());
-	System.out.println("T4 = " + T4.getLong());
+	if (DEBUG) {
+	    System.out.println("T1 = " + T1.getLong());
+	    System.out.println("T2 = " + T2.getLong());
+	    System.out.println("T3 = " + T3.getLong());
+	    System.out.println("T4 = " + T4.getLong());
+
+	    System.out.println("delay = " + delay);
+	    System.out.println("offset = " + offset);
+	}

-	System.out.println("delay = " + delay);
-	System.out.println("offset = " + offset);
-
     }


-    /// currently unused, could be useful for multi/anycast
+    /**
+     * receive NTP information (unused)
+     */
     public void receive() throws Exception {
-
+
+        /**
         //create empty packet
         byte[] data = new byte[40];
         DatagramPacket packet = new DatagramPacket(data,40);
@@ -180,10 +235,13 @@ public class SNTPClock {

         System.out.println("received: ");
         printByteArray(packet.getData());
-
+	*/
     }

-
+
+    /**
+     * create a valid NTP Request
+     */
     public byte[] createSNTPRequest() {

 	NTPTimeStamp ntptime = new NTPTimeStamp(timezone);
@@ -195,6 +253,8 @@ public class SNTPClock {
 	    output[i] = 0;
 	}

+	// just the bytes we need to fill in, hardcoded
+	// every request has the same first 4 bytes
 	output[0] = 35;
 	output[1] = 3;
 	output[2] = 10;
@@ -218,14 +278,29 @@ public class SNTPClock {
     }


-
+    /**
+     * test program
+     */
     public static void main(String args[]) throws Exception {

+	if (args.length < 2) {
+	    System.out.println("Usage: java SNTPClock <ntp server> <port>");
+	    System.exit(0);
+	}
+
 	SNTPClock sc = new SNTPClock(args[0], Integer.parseInt(args[1]), -5, 0);

+	long oldOffset = 0;
+
+	System.out.println("offset\t\tdelta");
+
 	while (true) {
 	    sc.sync();
-	    Thread.sleep(1000);
+	    Thread.sleep(2000);
+
+	    System.out.println(sc.getOffset() + "\t\t" + (sc.getOffset() - oldOffset));
+	    oldOffset = sc.getOffset();
+
 	}

     }