3 * Time-stamp: "2007-10-16 17:52:33 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
);
41 // if this node is a logging node
43 logFileName
= "lap-times-udp.log";
45 file
= new FileWriter(logFileName
);
46 out
= new BufferedWriter(file
);
48 catch (IOException e
) {
49 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 public boolean writeToLog() {
90 System
.out
.println("START TIME IS THIS: " + startTime
);
92 out
.write("Average lap time so far: " +
93 (System
.nanoTime() - startTime
)/(double) sentPackets
);
95 catch (IOException e
) {
96 System
.out
.println(e
);
101 public boolean closeLogFile() {
105 catch (IOException e
) {
106 System
.out
.println(e
);
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...
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
155 // if we left phase 1 but messages
156 // are still circling the ring:
157 if (phase
!= FINDMASTER
) {
158 // don't do anything.
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
) {
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,
185 // set the starting time -- the time
186 // when phase two was initiated
187 startTime
= System
.nanoTime();
189 // increase the number of sent packets.
192 // send first packet in phase two
193 sendPacket(constructPacket(INITRING
, new Integer(ID
).toString()));
196 // if messageType == 2
198 // make sure everybody knows we're in the second phase
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:
208 // increase the number of sent packets
211 System
.out
.println("--- WRITING TO LOG HERE WOO WOO! ---");
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;
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
);
229 // if messageType == 3 (stop sending packets and ultimately quit
231 runMainWhileLoop
= false;
232 // if this node is a logger, log one final time before
233 // stopping the whole shebang and close the file
238 // send terminating packet (end the whole shebang)
239 sendPacket(constructPacket(TERMINATE
, "3"));
241 // if a bogus message came into the ring (SOMEHOW...)
243 System
.out
.println("Message of unknown type -> " + messageType
);
246 } // end main while-loop
250 public static void main(String
[] args
) throws IOException
{
251 // args should contain local-port next-host next-port
253 boolean logger
= false;
254 if (args
.length
== 4 && args
[3].charAt(0) == 'L') {
258 node
= new UDPNode(Integer
.parseInt(args
[0]),
259 InetAddress
.getByName(args
[1]),
260 Integer
.parseInt(args
[2]),
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]");
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.");