3 * Time-stamp: "2007-10-18 12:54:36 spoof"
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
;
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
{
24 private DatagramSocket mySocket
= null;
26 public UDPNode(int localPort
,
32 super(localPort
, nextHost
, nextPort
, logger
);
33 // open a DatagramSocket
35 this.mySocket
= new DatagramSocket(localPort
);
37 catch (SocketException e
) {
38 System
.out
.println(e
);
42 // if this node is a logging node
44 logFileName
= "lap-times-udp.log";
46 file
= new FileWriter(logFileName
);
47 out
= new BufferedWriter(file
);
49 catch (IOException e
) {
50 System
.out
.println(e
);
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
) {
63 mySocket
.send(sendPacket
);
65 catch (IOException e
) {
66 System
.out
.println(e
);
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
) {
80 mySocket
.receive(receivePacket
);
82 catch (IOException e
) {
83 System
.out
.println(e
);
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...
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
132 // if we left phase 1 but messages
133 // are still circling the ring:
134 if (phase
!= FINDMASTER
) {
135 // don't do anything.
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
) {
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,
162 // set the starting time -- the time
163 // when phase two was initiated
164 startTime
= System
.nanoTime();
166 // increase the number of sent packets.
169 // send first packet in phase two
170 sendPacket(constructPacket(INITRING
, new Integer(ID
).toString()));
173 // if messageType == 2
175 // make sure everybody knows we're in the second phase
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:
185 // increase the number of sent packets
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"));
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 +
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
);
216 // if messageType == 3 (stop sending packets and ultimately quit
218 runMainWhileLoop
= false;
219 // if this node is a logger, log one final time before
220 // stopping the whole shebang and close the file
222 System
.out
.println("Closing file...");
226 // send terminating packet (end the whole shebang)
227 sendPacket(constructPacket(TERMINATE
, "3"));
229 // if a bogus message came into the ring (SOMEHOW...)
231 System
.out
.println("Message of unknown type -> " + messageType
);
234 } // end main while-loop
238 public static void main(String
[] args
) throws IOException
{
239 // args should contain local-port next-host next-port
241 boolean logger
= false;
242 if (args
.length
== 4 && args
[3].charAt(0) == 'L') {
246 node
= new UDPNode(Integer
.parseInt(args
[0]),
247 InetAddress
.getByName(args
[1]),
248 Integer
.parseInt(args
[2]),
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]");
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.");