Small changes, logging still not working.
[packetlaptime.git] / UDPNode.java
blobc50418c4a4556c86bf5d7e2b8dfb6d99114bfa0e
1 /*
2 * @(#)UDPNode.java
3 * Time-stamp: "2007-10-16 17:52:33 spoof"
4 */
6 import java.io.FileWriter;
7 import java.io.BufferedWriter;
8 import java.io.IOException;
10 import java.net.InetAddress;
11 import java.net.DatagramSocket;
12 import java.net.DatagramPacket;
13 import java.net.SocketException;
15 /**
16 * UDPNode – a node in a UDP packet ring.
18 * @author "Anton Johansson" <anton.johansson@gmail.com>
19 * @author "Victor Zamanian" <victor.zamanian@gmail.com>
21 public class UDPNode extends Node {
23 // This node's socket
24 private DatagramSocket mySocket = null;
26 public UDPNode(int localPort,
27 InetAddress nextHost,
28 int nextPort,
29 boolean logger) {
31 // initiate fields
32 super(localPort, nextHost, nextPort, logger);
33 // open a DatagramSocket
34 try {
35 this.mySocket = new DatagramSocket(localPort);
37 catch (SocketException e) {
38 System.out.println(e);
39 System.exit(1);
41 // if this node is a logging node
42 if (isLogger) {
43 logFileName = "lap-times-udp.log";
44 try {
45 file = new FileWriter(logFileName);
46 out = new BufferedWriter(file);
48 catch (IOException e) {
49 System.out.println(e);
50 System.exit(1);
53 } // end constructor
55 /**
56 * Sends a DatagramPacket through this UDPNode's DatagramSocket.
58 * @return boolean <code>true</code> if sending was successful,
59 * else <code>false</code>.
61 public boolean sendPacket(DatagramPacket sendPacket) {
62 try {
63 mySocket.send(sendPacket);
65 catch (IOException e) {
66 System.out.println(e);
67 return false;
69 return true;
72 /**
73 * Receives a DatagramPacket from this UDPNode's DatagramSocket.
75 * @return boolean <code>true</code> if receiving was successful,
76 * else <code>false</code>.
78 public boolean receivePacket(DatagramPacket receivePacket) {
79 try {
80 mySocket.receive(receivePacket);
82 catch (IOException e) {
83 System.out.println(e);
84 return false;
86 return true;
89 public boolean writeToLog() {
90 System.out.println("START TIME IS THIS: " + startTime);
91 try {
92 out.write("Average lap time so far: " +
93 (System.nanoTime() - startTime)/(double) sentPackets);
95 catch (IOException e) {
96 System.out.println(e);
97 return false;
99 return true;
101 public boolean closeLogFile() {
102 try {
103 out.close();
105 catch (IOException e) {
106 System.out.println(e);
107 return false;
109 return true;
112 // the method in which everything happens
113 public void runUDPNode() {
115 // keeps track of whether or not the
116 // main while-loop should be running
117 boolean runMainWhileLoop = true;
119 // start phase 1 by sending out a find-master query
120 sendPacket(constructPacket(FINDMASTER, new Integer(ID).toString()));
122 // initate fields used to store information from arrived packets
123 byte[] receivedData = new byte[DATAGRAMSIZE];
124 DatagramPacket receivePacket =
125 new DatagramPacket(receivedData, DATAGRAMSIZE);
127 // start receiving packets ('main while-loop')
128 while (runMainWhileLoop) {
129 // Waiting for data to arrive
130 receivePacket(receivePacket);
131 System.out.println("-- Packet arrived at port:"+localPort+" my ID:"+ID+"--");
133 // acquire the message's message type
134 int messageType = receivedData[0];
135 System.out.println("messageType -> " + messageType);
137 // acquire the message's length
138 int messageLength = receivedData[1];
140 // acquire the message...
141 String message =
142 new String(receivedData).substring(2, messageLength + 2);
143 System.out.println("message -> " + message + " @ port:"+localPort);
145 // the largest ID that this packet has seen so far, i.e. the
146 // ID of the node with the largest ID so far in the ring.
147 int receivedID = Integer.parseInt(message);
149 // keeping track of which phase we're in
150 int phase = FINDMASTER;
151 switch (messageType) {
152 // if messageType == 1
153 case FINDMASTER:
155 // if we left phase 1 but messages
156 // are still circling the ring:
157 if (phase != FINDMASTER) {
158 // don't do anything.
159 break;
161 // if this node will surely not be the master node
162 if (receivedID > ID) {
163 System.out.println("receivedID > ID" + " @ port:"+localPort);
165 // set a new receiver for the received packet
166 receivePacket.setPort(nextPort);
167 receivePacket.setAddress(nextHost);
168 sendPacket(receivePacket);
170 // if this node has a larger ID than the one of the sending node
171 else if (receivedID < ID) {
172 // Send own ID again since it could have been lost
173 System.out.println("receivedID < ID" + " @ port:"+localPort);
174 sendPacket(constructPacket(FINDMASTER, new Integer(ID).toString()));
176 // if this node should be the master node
177 else if (receivedID == ID) {
178 phase = INITRING;
179 isMasterNode = true;
180 System.out.println("receivedID == ID");
181 System.out.println("I am master, ID:"+ID+" Port:"+localPort);
183 // if this node is a logging node,
184 if (isLogger) {
185 // set the starting time -- the time
186 // when phase two was initiated
187 startTime = System.nanoTime();
189 // increase the number of sent packets.
190 sentPackets++;
192 // send first packet in phase two
193 sendPacket(constructPacket(INITRING, new Integer(ID).toString()));
195 break;
196 // if messageType == 2
197 case INITRING:
198 // make sure everybody knows we're in the second phase
199 phase = INITRING;
201 // if this node is a logger and the start time hasn't been set
202 if (isLogger && startTime == 0) {
203 // set the start time
204 startTime = System.nanoTime();
206 // if this node is a logger:
207 if (isLogger) {
208 // increase the number of sent packets
209 sentPackets++;
210 // write to file
211 System.out.println("--- WRITING TO LOG HERE WOO WOO! ---");
212 writeToLog();
213 // if we've sent as many packets as we were to:
214 if (sentPackets == PACKETSTOSEND) {
215 // send the terminating packet to the next node
216 // (and, indirectly so, to all other nodes)
217 sendPacket(constructPacket(TERMINATE, "3"));
218 runMainWhileLoop = false;
219 break;
223 // if we've not send as many packets as we are to:
224 // re-route packet (set its port and address) and send it
225 receivePacket.setPort(nextPort);
226 receivePacket.setAddress(nextHost);
227 sendPacket(receivePacket);
228 break;
229 // if messageType == 3 (stop sending packets and ultimately quit
230 case TERMINATE:
231 runMainWhileLoop = false;
232 // if this node is a logger, log one final time before
233 // stopping the whole shebang and close the file
234 if (isLogger) {
235 writeToLog();
236 closeLogFile();
238 // send terminating packet (end the whole shebang)
239 sendPacket(constructPacket(TERMINATE, "3"));
240 break;
241 // if a bogus message came into the ring (SOMEHOW...)
242 default:
243 System.out.println("Message of unknown type -> " + messageType);
244 break;
245 } // end switch
246 } // end main while-loop
247 } // end runUDPNode
249 // main...
250 public static void main(String[] args) throws IOException {
251 // args should contain local-port next-host next-port
252 UDPNode node = null;
253 boolean logger = false;
254 if (args.length == 4 && args[3].charAt(0) == 'L') {
255 logger = true;
257 try {
258 node = new UDPNode(Integer.parseInt(args[0]),
259 InetAddress.getByName(args[1]),
260 Integer.parseInt(args[2]),
261 logger);
263 catch (Exception e) {
264 System.out.println("You most likely provided parameters " +
265 "incorrectly to the program." + '\n' +
266 "Usage: java UDPNode local-port " +
267 "next-host next-port [L]");
268 System.exit(1);
270 try {
271 node.runUDPNode();
273 catch (Exception e) {
274 System.out.println("Something went wrong... Try making sure " +
275 "that the ports you are trying to use " +
276 "are not occupied by any other program.");