diff --git a/ws2012/P2P/uebungen/4/build.xml b/ws2012/P2P/uebungen/4/build.xml
new file mode 100644
index 00000000..c3a28e56
--- /dev/null
+++ b/ws2012/P2P/uebungen/4/build.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+ Builds, tests, and runs the project p2p_u4.
+
+
+
diff --git a/ws2012/P2P/uebungen/4/manifest.mf b/ws2012/P2P/uebungen/4/manifest.mf
new file mode 100644
index 00000000..328e8e5b
--- /dev/null
+++ b/ws2012/P2P/uebungen/4/manifest.mf
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+X-COMMENT: Main-Class will be added automatically by build
+
diff --git a/ws2012/P2P/uebungen/4/nbproject/build-impl.xml b/ws2012/P2P/uebungen/4/nbproject/build-impl.xml
new file mode 100644
index 00000000..6e719ec6
--- /dev/null
+++ b/ws2012/P2P/uebungen/4/nbproject/build-impl.xml
@@ -0,0 +1,924 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set platform.home
+ Must set platform.bootcp
+ Must set platform.java
+ Must set platform.javac
+
+ The J2SE Platform is not correctly set up.
+ Your active platform is: ${platform.active}, but the corresponding property "platforms.${platform.active}.home" is not found in the project's properties files.
+ Either open the project in the IDE and setup the Platform with the same name or add it manually.
+ For example like this:
+ ant -Duser.properties.file=<path_to_property_file> jar (where you put the property "platforms.${platform.active}.home" in a .properties file)
+ or ant -Dplatforms.${platform.active}.home=<path_to_JDK_home> jar (where no properties file is used)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set src.dir
+ Must set build.dir
+ Must set dist.dir
+ Must set build.classes.dir
+ Must set dist.javadoc.dir
+ Must set build.test.classes.dir
+ Must set build.test.results.dir
+ Must set build.classes.excludes
+ Must set dist.jar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ To run this application from the command line without Ant, try:
+
+
+
+
+
+
+ ${platform.java} -cp "${run.classpath.with.dist.jar}" ${main.class}
+
+
+
+
+
+
+
+
+
+
+
+ To run this application from the command line without Ant, try:
+
+ ${platform.java} -jar "${dist.jar.resolved}"
+
+
+
+
+
+
+
+ To run this application from the command line without Ant, try:
+
+ ${platform.java} -jar "${dist.jar.resolved}"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set debug.class
+
+
+
+
+ Must select one file in the IDE or set debug.class
+
+
+
+
+ Must set fix.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Some tests failed; see details above.
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set test.includes
+
+
+
+ Some tests failed; see details above.
+
+
+
+
+ Must select one file in the IDE or set test.class
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set applet.url
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set applet.url
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ws2012/P2P/uebungen/4/nbproject/genfiles.properties b/ws2012/P2P/uebungen/4/nbproject/genfiles.properties
new file mode 100644
index 00000000..463f74b7
--- /dev/null
+++ b/ws2012/P2P/uebungen/4/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=ca3c66c2
+build.xml.script.CRC32=a34fe718
+build.xml.stylesheet.CRC32=28e38971@1.38.3.45
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=ca3c66c2
+nbproject/build-impl.xml.script.CRC32=b618a294
+nbproject/build-impl.xml.stylesheet.CRC32=229523de@1.38.3.45
diff --git a/ws2012/P2P/uebungen/4/nbproject/private/config.properties b/ws2012/P2P/uebungen/4/nbproject/private/config.properties
new file mode 100644
index 00000000..e69de29b
diff --git a/ws2012/P2P/uebungen/4/nbproject/private/private.properties b/ws2012/P2P/uebungen/4/nbproject/private/private.properties
new file mode 100644
index 00000000..86cef05c
--- /dev/null
+++ b/ws2012/P2P/uebungen/4/nbproject/private/private.properties
@@ -0,0 +1,6 @@
+compile.on.save=true
+do.depend=false
+do.jar=true
+javac.debug=true
+javadoc.preview=true
+user.properties.file=C:\\Users\\rylon\\.netbeans\\6.9\\build.properties
diff --git a/ws2012/P2P/uebungen/4/nbproject/project.properties b/ws2012/P2P/uebungen/4/nbproject/project.properties
new file mode 100644
index 00000000..e791923d
--- /dev/null
+++ b/ws2012/P2P/uebungen/4/nbproject/project.properties
@@ -0,0 +1,73 @@
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=false
+annotation.processing.run.all.processors=true
+annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+application.title=p2p_u4
+application.vendor=rylon
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+# Uncomment to specify the preferred debugger connection transport:
+#debug.transport=dt_socket
+debug.classpath=\
+ ${run.classpath}
+debug.test.classpath=\
+ ${run.test.classpath}
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/p2p_u4.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+endorsed.classpath=
+excludes=
+file.reference.4-src=src
+includes=**
+jar.compress=false
+javac.classpath=
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.deprecation=false
+javac.processorpath=\
+ ${javac.classpath}
+javac.source=1.7
+javac.target=1.7
+javac.test.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}:\
+ ${libs.junit.classpath}:\
+ ${libs.junit_4.classpath}
+javac.test.processorpath=\
+ ${javac.test.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+main.class=
+manifest.file=manifest.mf
+meta.inf.dir=${src.dir}/META-INF
+platform.active=JDK_1.7
+run.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project
+# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
+# or test-sys-prop.name=value to set system properties for unit tests):
+run.jvmargs=
+run.test.classpath=\
+ ${javac.test.classpath}:\
+ ${build.test.classes.dir}
+source.encoding=UTF-8
+src.dir=${file.reference.4-src}
diff --git a/ws2012/P2P/uebungen/4/nbproject/project.xml b/ws2012/P2P/uebungen/4/nbproject/project.xml
new file mode 100644
index 00000000..f62bcc9d
--- /dev/null
+++ b/ws2012/P2P/uebungen/4/nbproject/project.xml
@@ -0,0 +1,14 @@
+
+
+ org.netbeans.modules.java.j2seproject
+
+
+ p2p_u4
+
+
+
+
+
+
+
+
diff --git a/ws2012/P2P/uebungen/4/src/Main.java b/ws2012/P2P/uebungen/4/src/Main.java
index f863742e..b6806d5f 100644
--- a/ws2012/P2P/uebungen/4/src/Main.java
+++ b/ws2012/P2P/uebungen/4/src/Main.java
@@ -9,66 +9,59 @@ import node.Node;
public class Main {
- public static Map nodes = new HashMap();
+ public static Map nodes = new HashMap<>();
- /**
- * grow a network: Starting with one peer, repeatedly let peers spawn or
- * leave at random
- *
- * @throws IOException
- */
- public static void main(String[] args) throws IOException {
+ /**
+ * grow a network: Starting with one peer, repeatedly let peers spawn or
+ * leave at random
+ *
+ * @param args
+ * @throws IOException
+ */
+ public static void main(String[] args) throws IOException {
- System.setProperty("java.util.logging.config.file",
- "logging.properties");
+ System.setProperty( "java.util.logging.config.file",
+ "logging.properties");
- try {
- LogManager.getLogManager().readConfiguration();
- }
+ try {
+ LogManager.getLogManager().readConfiguration();
+ } catch (Exception e) {
+ e.printStackTrace();}
- catch (Exception e) {
- e.printStackTrace();
- }
+ nodes.put("a", new Node());
- nodes.put("a", new Node());
+ BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+ String s;
+ while ((s = in.readLine()) != null && s.length() != 0) {
+ String[] splitted = s.split(" ");
- BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
- String s;
- while ((s = in.readLine()) != null && s.length() != 0) {
- String[] splitted = s.split(" ");
+ String node = splitted[0];
+ String cmd = splitted[1];
- String node = splitted[0];
- String cmd = splitted[1];
-
- if (nodes.containsKey(node)) {
-
- switch (cmd) {
- case "spawn":
- if (splitted.length > 2) {
- Node newNode = nodes.get(node).spawn();
- String newNodeName = splitted[2];
- nodes.put(newNodeName, newNode);
- } else {
- System.out
- .println("Please enter a name for the new node.");
- }
- break;
- case "leave":
- Node theNode = nodes.get(node);
- theNode.leave();
- nodes.remove(theNode);
- break;
- case "status":
- System.out.println(nodes.get(node));
- break;
- default:
- System.out.println("Unknown command.");
- break;
- }
-
- } else {
- System.out.println("No such node.");
- }
- }
- }
+ if (nodes.containsKey(node)) {
+ switch (cmd) {
+ case "spawn":
+ if (splitted.length > 2) {
+ Node newNode = nodes.get(node).spawn();
+ String newNodeName = splitted[2];
+ nodes.put(newNodeName, newNode);
+ } else {
+ System.out.println("Please enter a name for the new node.");}
+ break;
+ case "leave":
+ Node theNode = nodes.get(node);
+ theNode.leave();
+ nodes.remove(node);
+ break;
+ case "status":
+ System.out.println(nodes.get(node));
+ break;
+ default:
+ System.out.println("Unknown command.");
+ break;
+ }
+ } else {
+ System.out.println("No such node.");}
+ }
+ }
}
\ No newline at end of file
diff --git a/ws2012/P2P/uebungen/4/src/node/Node.java b/ws2012/P2P/uebungen/4/src/node/Node.java
index fe72c9de..6a664bff 100644
--- a/ws2012/P2P/uebungen/4/src/node/Node.java
+++ b/ws2012/P2P/uebungen/4/src/node/Node.java
@@ -10,330 +10,326 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
+import java.util.logging.Level;
import java.util.logging.Logger;
public class Node {
- private final static Logger LOGGER = Logger.getLogger(Node.class.getName());
+ private final static Logger LOGGER = Logger.getLogger(Node.class.getName());
- private static final int BUF_SIZE = 512;
+ private static final int BUF_SIZE = 512;
- private DatagramChannel channel;
- private ByteBuffer buf;
+ private DatagramChannel channel;
+ private ByteBuffer buf;
- private String name = "Not initialized";
+ private String name = "Not initialized";
- private List neighbors = new ArrayList();
+ private List neighbors = new ArrayList<>();
- private Map acks = new HashMap();
+ private Map acks = new HashMap<>();
- private volatile Thread thread;
- private UDPListen udpListen;
+ private volatile Thread thread;
+ private UDPListen udpListen;
- private Random generator;
+ private Random generator;
- public Node() {
- System.setProperty("java.net.preferIPv4Stack", "true");
- generator = new Random(System.currentTimeMillis());
- try {
- channel = DatagramChannel.open();
- channel.socket().bind(new InetSocketAddress("localhost", 0));
- channel.configureBlocking(false);
+ public Node() {
+ //debug
+ System.setProperty("java.net.preferIPv4Stack", "true");
+ generator = new Random(System.currentTimeMillis());
+ try {
+ channel = DatagramChannel.open();
+ channel.socket().bind(new InetSocketAddress("localhost", 0));
+ channel.configureBlocking(false);
- buf = ByteBuffer.allocate(BUF_SIZE);
+ buf = ByteBuffer.allocate(BUF_SIZE);
- this.name = channel.socket().getLocalSocketAddress().toString();
+ this.name = channel.socket().getLocalSocketAddress().toString();
- udpListen = new UDPListen();
- thread = new Thread(udpListen);
- thread.start();
+ udpListen = new UDPListen();
+ thread = new Thread(udpListen);
- LOGGER.info("Initialized node " + name);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
+ LOGGER.log(Level.INFO, "Initialized node {0}", name);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
- /**
- * Create another peer, mutually link creator and spawn.
- *
- * @return the spawned Node
- * @throws IOException
- * if no connection could be established to the new node
- */
- public Node spawn() throws IOException {
- // LOGGER.info("Name: " + getName() + ", Spawning new node.");
- Node newNode = new Node();
+ /**
+ * Create another peer, mutually link creator and spawn.
+ *
+ * @return the spawned Node
+ * @throws IOException
+ * if no connection could be established to the new node
+ */
+ public Node spawn() throws IOException {
+ // LOGGER.info("Name: " + getName() + ", Spawning new node.");
+ Node newNode = new Node();
+
+ Send_Invite(newNode);
+ neighbors.add(newNode.getAddress());
- int ack_id = generateAck(newNode.getAddress());
- buf.clear();
- buf.put(MessageType.INVITE);
- buf.putInt(ack_id);
- buf.flip();
+ return newNode;
+ }
- try {
- channel.send(buf, newNode.getAddress());
- } catch (IOException e) {
- e.printStackTrace();
- }
+ public boolean Send_Invite(Node newNode){
+ ByteBuffer buffer = ByteBuffer.allocate(BUF_SIZE);
+ int ack_id = generateAck(newNode.getAddress());
+ buffer.put(MessageType.INVITE);
+ buffer.putInt(ack_id);
+ buffer.flip();
- neighbors.add(newNode.getAddress());
+ try {
+ channel.send(buffer, newNode.getAddress());
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
- return newNode;
- }
+ /**
+ * Adds a new ack, which this node is expecting to receive.
+ *
+ * @param addr
+ * the SocketAddress the ack should be received from
+ * @return the identifier for this ack
+ */
+ private int generateAck(SocketAddress addr) {
+ int ack_id = generator.nextInt();
+ acks.put(ack_id, new Ack(addr));
+ return ack_id;
+ }
- /**
- * Adds a new ack, which this node is expecting to receive.
- *
- * @param addr
- * the SocketAddress the ack should be received from
- * @return the identifier for this ack
- */
- public int generateAck(SocketAddress addr) {
- int ack_id = generator.nextInt();
- acks.put(ack_id, new Ack(addr));
- return ack_id;
- }
+ public SocketAddress getAddress() {
+ return channel.socket().getLocalSocketAddress();}
- public SocketAddress getAddress() {
- return channel.socket().getLocalSocketAddress();
- }
+ public boolean Send_NewNeighbor(SocketAddress receiver, SocketAddress neighbor){
+ ByteBuffer buffer = ByteBuffer.allocate(BUF_SIZE);
+ int ack_id = generateAck(neighbor);
+ buffer.put(MessageType.NEW_NEIGHBOR);
+ buffer.putInt(ack_id);
+ InetSocketAddress a = (InetSocketAddress) neighbor;
+ for (String part : a.getHostString().split("\\.")) {
+ buffer.put(Byte.valueOf(part));}
+ buffer.putInt(a.getPort());
+ buffer.flip();
- private void sendAddrTo(SocketAddress receiver, SocketAddress addr) {
- InetSocketAddress a = (InetSocketAddress) addr;
- int ack_id = generateAck(addr);
+ try {
+ channel.send(buffer, receiver);
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
- buf.clear();
- buf.put(MessageType.NEW_NEIGHBOR);
- buf.putInt(ack_id);
+ /**
+ * Sends an acknowledgment message to receiver (who hopefully is expecting
+ * it)
+ *
+ * @param receiver
+ * the node expecting an ack
+ * @param ack_id
+ * the id to identify the ack
+ */
+ private boolean Send_Ack(SocketAddress receiver, int ack_id) {
+ ByteBuffer buffer = ByteBuffer.allocate(BUF_SIZE);
+ buffer.put(MessageType.ACK);
+ buffer.putInt(ack_id);
+ buffer.flip();
+ try {
+ channel.send(buffer, receiver);
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
- for (String part : a.getHostString().split("\\.")) {
- buf.put(Byte.valueOf(part));
- }
- buf.putInt(a.getPort());
+ private boolean Send_Leave(SocketAddress neighbor){
+ ByteBuffer buffer = ByteBuffer.allocate(BUF_SIZE);
+ int ack_id = generateAck(neighbor);
+ buffer.put(MessageType.LEAVE);
+ buffer.putInt(ack_id);
+ buffer.flip();
- // acks.get(ack_id).setBuf(BufferUtil.clone(buf));
+ try {
+ channel.send(buffer, neighbor);
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+ /**
+ * This node circularly links all neighbors (no mesh!) and removes itself
+ * from the network.
+ */
+ public void leave() {
+ LOGGER.log(Level.INFO, "Name: {0}, Leaving...", getName());
- buf.flip();
- try {
- channel.send(buf, receiver);
- } catch (IOException e) {
- // TODO
- }
- }
+ for (int i = 0; i < neighbors.size(); i++) {
+ if (neighbors.size() > 2) {
+ int pred = ((i - 1) + neighbors.size()) % neighbors.size();
+ int succ = (i + 1) % neighbors.size();
+ Send_NewNeighbor(neighbors.get(i), neighbors.get(succ));
+ Send_NewNeighbor(neighbors.get(i), neighbors.get(pred));
+ } else if (neighbors.size() == 2) {
+ Send_NewNeighbor(neighbors.get(i), neighbors.get(Math.abs(i - 1)));
+ }
- /**
- * Sends an acknowledgment message to receiver (who hopefully is expecting
- * it)
- *
- * @param receiver
- * the node expecting an ack
- * @param ack_id
- * the id to identify the ack
- */
- private void sendAckTo(SocketAddress receiver, int ack_id) {
- buf.clear();
- buf.put(MessageType.ACK);
- buf.putInt(ack_id);
- buf.flip();
- try {
- channel.send(buf, receiver);
- } catch (IOException e) {
- // TODO
- }
- }
+ Send_Leave(neighbors.get(i));
+ }
- /**
- * This node circularly links all neighbors (no mesh!) and removes itself
- * from the network.
- */
- public void leave() {
- LOGGER.info("Name: " + getName() + ", Leaving...");
+ try {
+ if (thread != null) {
+ udpListen.terminate();
+ thread.join();}
+ } catch (InterruptedException e) {
+ e.printStackTrace();}
+ }
- for (int i = 0; i < neighbors.size(); i++) {
+ public boolean hasNeighbor(SocketAddress addr) {
+ for (SocketAddress n : neighbors) {
+ if (n.toString().equals(addr.toString())) {
+ return true;
+ }
+ }
+ return false;
+ }
- if (neighbors.size() > 2) {
- int pred = ((i - 1) + neighbors.size()) % neighbors.size();
- int succ = (i + 1) % neighbors.size();
- sendAddrTo(neighbors.get(i), neighbors.get(succ));
- sendAddrTo(neighbors.get(i), neighbors.get(pred));
- } else if (neighbors.size() == 2) {
- sendAddrTo(neighbors.get(i), neighbors.get(Math.abs(i - 1)));
- }
+ public int getNeighborId(SocketAddress addr) {
+ for (int i = 0; i < neighbors.size(); i++) {
+ if (neighbors.get(i).toString().equals(addr.toString())) {
+ return i;
+ }
+ }
+ return -1;
+ }
- buf.clear();
- int ack_id = generateAck(neighbors.get(i));
- buf.put(MessageType.LEAVE);
- buf.putInt(ack_id);
- buf.flip();
+ public String getName() {
+ return this.name;}
- try {
- channel.send(buf, neighbors.get(i));
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- try {
- if (thread != null) {
- udpListen.terminate();
- thread.join();
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
+ public String toString() {
+ StringBuilder result = new StringBuilder(256);
+ result.append("Node ");
+ result.append(getName()).append(", Neighbors: ");
+ result.append(neighbors);
+ return result.toString();
+ }
- public boolean hasNeighbor(SocketAddress addr) {
- for (SocketAddress n : neighbors) {
- if (n.toString().equals(addr.toString())) {
- return true;
- }
- }
- return false;
- }
+ private class UDPListen implements Runnable {
+ private volatile boolean running = true;
- public int getNeighborId(SocketAddress addr) {
- for (int i = 0; i < neighbors.size(); i++) {
- if (neighbors.get(i).toString().equals(addr.toString())) {
- return i;
- }
- }
- return -1;
- }
+ private void Receive_Invite(SocketAddress from){
+ LOGGER.log(Level.INFO, "{0} received invite from {1}", new Object[]{name, from.toString()});
+ int ack_id = buf.getInt();
+ Send_Ack(from, ack_id);
+ neighbors.add(from);
+ }
- public String getName() {
- return this.name;
- }
+ private void Receive_Ack(SocketAddress from){
+ LOGGER.log(Level.INFO, "{0} received ack from {1}", new Object[]{name, from.toString()});
+ int ack_id = buf.getInt();
+ if (!checkAck(from, ack_id)) {
+ LOGGER.log(Level.WARNING, "Received unexpected ack from: {0}", from.toString());}
+ }
- public String toString() {
- StringBuilder result = new StringBuilder(256);
- result.append("Node ");
- result.append(getName()).append(", Neighbors: ");
- result.append(neighbors);
- return result.toString();
- }
+ private void Receive_Leave(SocketAddress from){
+ LOGGER.log(Level.INFO, "{0}: {1} is leaving. Deleting...", new Object[]{name, from.toString()});
- public class UDPListen implements Runnable {
- private volatile boolean running = true;
+ int idToRemove = getNeighborId(from);
+ if (idToRemove != -1) {
+ neighbors.remove(idToRemove);
+ int ack_id = buf.getInt();
+ Send_Ack(from, ack_id);
+ }
+ // If we don't know that neighbor, we don't have to
+ // ack
+ }
- public void run() {
- SocketAddress receivedFrom = null;
- int ack_id;
+ private void Receive_NewNeighbor(SocketAddress from){
+ int ack_id = buf.getInt();
+ StringBuilder theAddr = new StringBuilder();
- while (running) {
- try {
- receivedFrom = channel.receive(buf);
+ // Read 4 Bytes and 1 Integer = 1 IP address
+ for (int i = 0; i < 4; i++) {
+ theAddr.append(buf.get());
+ if (i < 3){
+ theAddr.append(".");}
+ }
+ int port = buf.getInt();
- // channel.receive() is non blocking. So we need to check if
- // something actually has been written to the buffer
- if (buf.remaining() != BUF_SIZE) {
- buf.flip();
+ InetSocketAddress new_neighbor = new InetSocketAddress(theAddr.toString(), port);
- byte messageType = buf.get();
+ if (!hasNeighbor(new_neighbor)) {
+ // Add this neighbor to my neighbor list if it
+ // was not present before
+ neighbors.add(new_neighbor);
- switch (messageType) {
- case MessageType.INVITE:
- LOGGER.info(name + " received invite from "
- + receivedFrom.toString());
+ LOGGER.log(Level.INFO, "{0} from {1} received new neighbor:{2}", new Object[]{name, from.toString(), new_neighbor.toString()});
+ }
- ack_id = buf.getInt();
+ Send_Ack(from, ack_id);
+ }
- sendAckTo(receivedFrom, ack_id);
+ public void run() {
+ SocketAddress receivedFrom = null;
- neighbors.add(receivedFrom);
- break;
+ while (running) {
+ try {
+ receivedFrom = channel.receive(buf);
- case MessageType.ACK:
- ack_id = buf.getInt();
+ // channel.receive() is non blocking. So we need to check if
+ // something actually has been written to the buffer
+ if (buf.remaining() != BUF_SIZE) {
+ buf.flip();
- LOGGER.info(name + " received ack from "
- + receivedFrom.toString());
+ byte messageType = buf.get();
- if (!checkAck(receivedFrom, ack_id)) {
- LOGGER.warning("Received unexpected ack from: "
- + receivedFrom.toString());
- }
+ switch (messageType) {
+ case MessageType.INVITE:
+ Receive_Invite(receivedFrom);
+ break;
+ case MessageType.ACK:
+ Receive_Ack(receivedFrom);
+ break;
+ case MessageType.LEAVE:
+ Receive_Leave(receivedFrom);
+ break;
+ case MessageType.NEW_NEIGHBOR:
+ Receive_NewNeighbor(receivedFrom);
+ break;
+ default:
+ LOGGER.log(Level.INFO, "{0} received unknown command from {1}: [{2}]{3}", new Object[]{name, receivedFrom.toString(), messageType, new String(buf.array())});
+ }
+ } else {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ buf.clear();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
- break;
+ private boolean checkAck(SocketAddress receivedFrom, int ack_id) {
+ if (acks.containsKey(ack_id)) {
+ Ack theAck = acks.get(ack_id);
+ if (theAck.check(receivedFrom)) {
+ acks.remove(ack_id);
+ return true;
+ }
+ }
+ return false;
+ }
- case MessageType.LEAVE:
- LOGGER.info(name + ": " + receivedFrom.toString()
- + " is leaving. Deleting...");
-
- int idToRemove = getNeighborId(receivedFrom);
- if (idToRemove != -1) {
- neighbors.remove(idToRemove);
- ack_id = buf.getInt();
- sendAckTo(receivedFrom, ack_id);
- }
- // If we don't know that neighbor, we don't have to
- // ack
- break;
-
- case MessageType.NEW_NEIGHBOR:
- ack_id = buf.getInt();
- StringBuilder theAddr = new StringBuilder();
-
- // Read 4 Bytes and 1 Integer = 1 IP address
- for (int i = 0; i < 4; i++) {
- theAddr.append(buf.get());
- if (i < 3)
- theAddr.append(".");
- }
- int port = buf.getInt();
-
- InetSocketAddress new_neighbor = new InetSocketAddress(
- theAddr.toString(), port);
-
- if (!hasNeighbor(new_neighbor)) {
- // Add this neighbor to my neighbor list if it
- // was not present before
- neighbors.add(new_neighbor);
-
- LOGGER.info(name + " from "
- + receivedFrom.toString()
- + " received new neighbor:"
- + new_neighbor.toString());
- }
-
- sendAckTo(receivedFrom, ack_id);
-
- break;
-
- default:
- LOGGER.info(name
- + " received unknown command from "
- + receivedFrom.toString() + ": ["
- + messageType + "]"
- + new String(buf.array()));
- }
- } else {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- buf.clear();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- private boolean checkAck(SocketAddress receivedFrom, int ack_id) {
- if (acks.containsKey(ack_id)) {
- Ack theAck = acks.get(ack_id);
- if (theAck.check(receivedFrom)) {
- acks.remove(theAck);
- return true;
- }
- }
- return false;
- }
-
- public void terminate() {
- running = false;
- }
- }
+ public void terminate() {
+ running = false;}
+ }
}