prrroff
[packetlaptime.git] / Node.java
blob1e0e4acf2c34b57f502921d4522ca93cddf77057
1 /*
2 * @(#)Node.java
3 * Time-stamp: "2007-10-30 20:36:14 anton"
4 */
6 import java.util.Random;
8 import java.io.FileWriter;
9 import java.io.BufferedWriter;
10 import java.io.IOException;
12 import java.net.InetAddress;
13 import java.net.DatagramPacket;
14 import java.net.SocketException;
16 /**
17 * Node – a node in a packet ring.
19 * @author "Anton Johansson" <anton.johansson@gmail.com>
20 * @author "Victor Zamanian" <victor.zamanian@gmail.com>
22 public abstract class Node implements NodeInterface {
24 // general Node information
25 protected final int localPort;
26 protected final InetAddress nextHost;
27 protected final int nextPort;
28 protected final int ID;
29 // the time when the logging starts
30 protected long startTime = 0;
32 // keeps track of whether this Node
33 // is a master node (sends the first message)
34 // and/or a logger (logs lap times to a file)
35 protected boolean isMasterNode = false;
36 protected boolean isLogger = false;
38 // log file fields
39 protected String logFileName = null;
40 protected FileWriter file = null;
41 protected BufferedWriter out = null;
43 // different message types
44 protected final int FINDMASTER = 1;
45 protected final int RUNMODE = 2;
46 protected final int TERMINATE = 3;
47 // message datagram size
48 protected final int DATAGRAMSIZE = 100;
49 // All IDs have 10 figures and range from
50 // 10^9 to the maximum value of an int.
51 private final int IDRANGE = Integer.MAX_VALUE - (int) Math.pow(10,9);
53 // number of packets to send in the ring
54 // If PACKETSTOSEND is set to 0, the rings will
55 // go on until the program is interrupted.
56 protected final int PACKETSTOSEND = 10000;
57 // needed to calculate lap times
58 protected int sentPackets = 0;
60 /**
61 * Constructs a new object instance of the Node class.
63 public Node(int localPort,
64 InetAddress nextHost,
65 int nextPort,
66 boolean logger) {
68 // set some fields
69 this.ID = (int) Math.pow(10,9) + (new Random().nextInt(IDRANGE));
70 this.localPort = localPort;
71 this.nextHost = nextHost;
72 this.nextPort = nextPort;
73 this.isLogger = logger;
74 // print some information about this node
75 System.out.println("\n----------(ID = " + ID + ")----------\n" +
76 "Node listens on port no.: " + localPort +
77 "\nNext host in ring is: " + nextHost +
78 "\nNext host listens on port no.: " + nextPort);
81 /**
82 * Sends a DatagramPacket through this Node's socket.
83 * NOTE: Since the Node class is really just a container
84 * for methods and fields for the subclasses of the Node class,
85 * this methods does nothing but return 'false' because the
86 * method of sending packets differ between UDPNode and TCPNode.
88 * @return boolean Whether or not the sending was successful.
90 public abstract boolean sendPacket(DatagramPacket sendPacket);
92 /**
93 * Receives a DatagramPacket from this Node's socket.
94 * NOTE: This method does nothing but return 'false',
95 * because: see note at sendPacket(DatagramPacket sendPacket).
97 * @return boolean Whether or not the receiving was successful.
99 public abstract boolean receivePacket(DatagramPacket receivePacket);
103 * Constructs a byte-array with first the messageType in the first
104 * byte and the message in following
106 * @param messageType the type of the message
107 * @param message the message
108 * @return a byte-array first byte is messageType rest is message
110 public byte[] constructByteArray(int messageType, String message) {
111 if (message == null) {
112 message = "";
115 byte[] sendBytes = new byte[DATAGRAMSIZE];
116 sendBytes[0] = (byte) messageType;
117 sendBytes[1] = message.length() < (DATAGRAMSIZE-2) ? (byte) message.length() : (byte) (DATAGRAMSIZE-2);
119 for (int i=0; i<sendBytes[1]; i++) {
120 sendBytes[2 + i] = (byte) message.charAt(i);
122 return sendBytes;
126 * Constructs a DatagramPacket with an InetAddress, a port,
127 * a message type and a message. The method asserts that the
128 * message is not of greater length than the DatagramPacket's
129 * maximum length.
131 * @return DatagramPacket The packet constructed by this method.
133 public DatagramPacket constructPacket(int messageType, String message) {
134 byte[] sendBytes = constructByteArray(messageType, message);
135 return new DatagramPacket(sendBytes,
136 sendBytes.length,
137 nextHost,
138 nextPort);
143 * Writes the lap times to a log file.
145 * @return boolean <code>true</code> if writing to the log file
146 * was successful, <code>false</code> if not.
148 public boolean writeToLog(String id) {
149 try {
150 out.write("Average time so far: " +
151 (System.nanoTime() -
152 startTime)/(double)sentPackets +
153 " ns, ID = " + id + "\n");
155 catch (IOException e) {
156 System.out.println(e);
157 return false;
159 return true;
163 * Closes the log file to which the lap times are written.
165 * @return boolean <code>true</code> if closing the file was
166 * successful, <code>false</code> if not.
168 public boolean closeLogFile() {
169 try {
170 out.close();
172 catch (IOException e) {
173 System.out.println(e);
174 return false;
176 return true;