copy paste seems like everything works? Have to check though
[packetlaptime.git] / UDPNode.java
bloba10203e9a3b1f79c46e0600fcb58b113a90b8ee8
1 /*
2 * @(#)UDPNode.java
3 * Time-stamp: "2007-10-18 12:54:36 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);
42 // if this node is a logging node
43 if (isLogger) {
44 logFileName = "lap-times-udp.log";
45 try {
46 file = new FileWriter(logFileName);
47 out = new BufferedWriter(file);
49 catch (IOException e) {
50 System.out.println(e);
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 // the method in which everything happens
90 public void runUDPNode() {
92 // keeps track of whether or not the
93 // main while-loop should be running
94 boolean runMainWhileLoop = true;
96 // start phase 1 by sending out a find-master query
97 sendPacket(constructPacket(FINDMASTER, new Integer(ID).toString()));
99 // initate fields used to store information from arrived packets
100 byte[] receivedData = new byte[DATAGRAMSIZE];
101 DatagramPacket receivePacket =
102 new DatagramPacket(receivedData, DATAGRAMSIZE);
104 // start receiving packets ('main while-loop')
105 while (runMainWhileLoop) {
106 // Waiting for data to arrive
107 receivePacket(receivePacket);
108 System.out.println("-- Packet arrived at port:"+localPort+" my ID:"+ID+"--");
110 // acquire the message's message type
111 int messageType = receivedData[0];
112 System.out.println("messageType -> " + messageType);
114 // acquire the message's length
115 int messageLength = receivedData[1];
117 // acquire the message...
118 String message =
119 new String(receivedData).substring(2, messageLength + 2);
120 System.out.println("message -> " + message + " @ port:"+localPort);
122 // the largest ID that this packet has seen so far, i.e. the
123 // ID of the node with the largest ID so far in the ring.
124 int receivedID = Integer.parseInt(message);
126 // keeping track of which phase we're in
127 int phase = FINDMASTER;
128 switch (messageType) {
129 // if messageType == 1
130 case FINDMASTER:
132 // if we left phase 1 but messages
133 // are still circling the ring:
134 if (phase != FINDMASTER) {
135 // don't do anything.
136 break;
138 // if this node will surely not be the master node
139 if (receivedID > ID) {
140 System.out.println("receivedID > ID" + " @ port:"+localPort);
142 // set a new receiver for the received packet
143 receivePacket.setPort(nextPort);
144 receivePacket.setAddress(nextHost);
145 sendPacket(receivePacket);
147 // if this node has a larger ID than the one of the sending node
148 else if (receivedID < ID) {
149 // Send own ID again since it could have been lost
150 System.out.println("receivedID < ID" + " @ port:"+localPort);
151 sendPacket(constructPacket(FINDMASTER, new Integer(ID).toString()));
153 // if this node should be the master node
154 else if (receivedID == ID) {
155 phase = INITRING;
156 isMasterNode = true;
157 System.out.println("receivedID == ID");
158 System.out.println("I am master, ID:"+ID+" Port:"+localPort);
160 // if this node is a logging node,
161 if (isLogger) {
162 // set the starting time -- the time
163 // when phase two was initiated
164 startTime = System.nanoTime();
166 // increase the number of sent packets.
167 sentPackets++;
169 // send first packet in phase two
170 sendPacket(constructPacket(INITRING, new Integer(ID).toString()));
172 break;
173 // if messageType == 2
174 case INITRING:
175 // make sure everybody knows we're in the second phase
176 phase = INITRING;
178 // if this node is a logger and the start time hasn't been set
179 if (isLogger && startTime == 0) {
180 // set the start time
181 startTime = System.nanoTime();
183 // if this node is a logger:
184 if (isLogger) {
185 // increase the number of sent packets
186 sentPackets++;
187 // write to file
188 writeToLog();
189 // if we've sent as many packets as we were to (and the
190 // number of packets to send is not zero (infinitely many)):
191 if (sentPackets == PACKETSTOSEND && PACKETSTOSEND != 0) {
192 // send the terminating packet to the next node
193 // (and, indirectly so, to all other nodes)
194 sendPacket(constructPacket(TERMINATE, "3"));
195 break;
198 // if this node is the master node, make it print out
199 // what the logging node is writing to the log file, so
200 // that we can actally see things happening as well.
201 // NOTE: UNCOMMENT WHEN ALL DEBUGGING PRINTOUTS HAVE BEEN REMOVED
202 // SO THAT THE DEGUGGING PRINTOUTS AREN'T LOST COMPLETELY...
203 // if (isMasterNode) {
204 // System.out.println("Average lap time so far: " +
205 // (System.nanoTime() -
206 // startTime)/(double)sentPackets +
207 // " ns");
208 // }
210 // if we've not send as many packets as we are to:
211 // re-route packet (set its port and address) and send it
212 receivePacket.setPort(nextPort);
213 receivePacket.setAddress(nextHost);
214 sendPacket(receivePacket);
215 break;
216 // if messageType == 3 (stop sending packets and ultimately quit
217 case TERMINATE:
218 runMainWhileLoop = false;
219 // if this node is a logger, log one final time before
220 // stopping the whole shebang and close the file
221 if (isLogger) {
222 System.out.println("Closing file...");
223 writeToLog();
224 closeLogFile();
226 // send terminating packet (end the whole shebang)
227 sendPacket(constructPacket(TERMINATE, "3"));
228 break;
229 // if a bogus message came into the ring (SOMEHOW...)
230 default:
231 System.out.println("Message of unknown type -> " + messageType);
232 break;
233 } // end switch
234 } // end main while-loop
235 } // end runUDPNode
237 // main...
238 public static void main(String[] args) throws IOException {
239 // args should contain local-port next-host next-port
240 UDPNode node = null;
241 boolean logger = false;
242 if (args.length == 4 && args[3].charAt(0) == 'L') {
243 logger = true;
245 try {
246 node = new UDPNode(Integer.parseInt(args[0]),
247 InetAddress.getByName(args[1]),
248 Integer.parseInt(args[2]),
249 logger);
251 catch (Exception e) {
252 System.out.println("You most likely provided parameters " +
253 "incorrectly to the program." + '\n' +
254 "Usage: java UDPNode local-port " +
255 "next-host next-port [L]");
256 System.exit(1);
258 try {
259 node.runUDPNode();
261 catch (Exception e) {
262 System.out.println("Something went wrong... Try making sure " +
263 "that the ports you are trying to use " +
264 "are not occupied by any other program.");