Switched to real network communication, not just calling methods on objects
This commit is contained in:
parent
a7043d1522
commit
303042078c
BIN
ws2011/BP/Auftraggebertreffen/.DS_Store
vendored
BIN
ws2011/BP/Auftraggebertreffen/.DS_Store
vendored
Binary file not shown.
BIN
ws2011/BP/Datenbank Backups/.DS_Store
vendored
BIN
ws2011/BP/Datenbank Backups/.DS_Store
vendored
Binary file not shown.
BIN
ws2011/BP/QS-Dokument/.DS_Store
vendored
BIN
ws2011/BP/QS-Dokument/.DS_Store
vendored
Binary file not shown.
BIN
ws2011/BP/Wiki-Stuff/.DS_Store
vendored
BIN
ws2011/BP/Wiki-Stuff/.DS_Store
vendored
Binary file not shown.
BIN
ws2011/Compiler I/Triangle-2.1-esa3/.DS_Store
vendored
BIN
ws2011/Compiler I/Triangle-2.1-esa3/.DS_Store
vendored
Binary file not shown.
Binary file not shown.
BIN
ws2011/Compiler I/Uebungen/2. Uebung/.DS_Store
vendored
BIN
ws2011/Compiler I/Uebungen/2. Uebung/.DS_Store
vendored
Binary file not shown.
BIN
ws2011/Compiler I/Uebungen/3. Uebung/.DS_Store
vendored
BIN
ws2011/Compiler I/Uebungen/3. Uebung/.DS_Store
vendored
Binary file not shown.
BIN
ws2011/FOC/Folien/.DS_Store
vendored
BIN
ws2011/FOC/Folien/.DS_Store
vendored
Binary file not shown.
BIN
ws2011/FOC/Klausurvorbereitung/Klausuren/.DS_Store
vendored
BIN
ws2011/FOC/Klausurvorbereitung/Klausuren/.DS_Store
vendored
Binary file not shown.
BIN
ws2011/Semantic Web/Folien/.DS_Store
vendored
BIN
ws2011/Semantic Web/Folien/.DS_Store
vendored
Binary file not shown.
BIN
ws2011/Semantic Web/Praesentation/.DS_Store
vendored
BIN
ws2011/Semantic Web/Praesentation/.DS_Store
vendored
Binary file not shown.
BIN
ws2011/Semantic Web/Uebungen/.DS_Store
vendored
BIN
ws2011/Semantic Web/Uebungen/.DS_Store
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,7 +1,9 @@
|
||||
package common;
|
||||
|
||||
public class MessageType {
|
||||
public final static byte BOOTSTRAP = 0;
|
||||
public final static byte INVITE = 7;
|
||||
public final static byte LEAVE = 1;
|
||||
public final static byte NEW_NEIGHBOUR = 1;
|
||||
|
||||
public final static byte NEW_NEIGHBOR_IPV4 = 4;
|
||||
public final static byte NEW_NEIGHBOR_IPV6 = 6;
|
||||
}
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
package network;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.logging.LogManager;
|
||||
|
||||
import peer.Peer;
|
||||
import peer.Node;
|
||||
|
||||
public class Network {
|
||||
|
||||
@ -23,12 +24,20 @@ public class Network {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Peer a = new Peer("A");
|
||||
Node a = new Node();
|
||||
|
||||
a.spawn("B");
|
||||
a.spawn("C");
|
||||
a.spawn("D");
|
||||
a.leave();
|
||||
try {
|
||||
Node b = a.spawn();
|
||||
Node c = a.spawn();
|
||||
Node d = a.spawn();
|
||||
|
||||
a.leave();
|
||||
b.leave();
|
||||
c.leave();
|
||||
d.leave();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,125 +1,215 @@
|
||||
package peer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.DatagramChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import common.MessageType;
|
||||
|
||||
public class Node {
|
||||
|
||||
private final static Logger LOGGER = Logger.getLogger(Node.class.getName());
|
||||
|
||||
// node id must be unique! id = IP of peer ?!?
|
||||
// -> Should be unique if we don't consider peers behind a NAT.
|
||||
private int id;
|
||||
private static final int BUF_SIZE = 256;
|
||||
|
||||
private String name;
|
||||
private DatagramChannel channel;
|
||||
private ByteBuffer buf;
|
||||
|
||||
private List<Node> neighbours = new ArrayList<Node>();
|
||||
private String name = "Not initialized";
|
||||
|
||||
public Node(int id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
private List<SocketAddress> neighbors = new ArrayList<SocketAddress>();
|
||||
|
||||
private Thread thread;
|
||||
private UDPListen udpListen;
|
||||
|
||||
public Node() {
|
||||
try {
|
||||
channel = DatagramChannel.open();
|
||||
channel.socket().bind(null);
|
||||
buf = ByteBuffer.allocate(BUF_SIZE);
|
||||
|
||||
this.name = channel.getLocalAddress().toString();
|
||||
|
||||
udpListen = new UDPListen();
|
||||
thread = new Thread(udpListen);
|
||||
thread.start();
|
||||
|
||||
LOGGER.info("Initialized node " + name);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add one single neighbour
|
||||
* Create another peer, mutually link creator and spawn.
|
||||
*
|
||||
* @param neighbour
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public void addSingleNeighbour(Node neighbour) {
|
||||
public Node spawn() throws IOException {
|
||||
LOGGER.info("Name: " + getName() + ", Spawning new node.");
|
||||
|
||||
Iterator<Node> it = this.neighbours.iterator();
|
||||
// create a new node
|
||||
Node newNode = new Node();
|
||||
|
||||
if (!it.hasNext()) { // list of neighbours is empty
|
||||
this.neighbours.add(neighbour);
|
||||
} else {
|
||||
// check if neighbour is already in list
|
||||
while (it.hasNext()) {
|
||||
if (it.next().getId() == neighbour.getId()) {
|
||||
return;
|
||||
buf.clear();
|
||||
buf.put(MessageType.INVITE);
|
||||
buf.flip();
|
||||
|
||||
try {
|
||||
channel.send(buf, newNode.getAddress());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
neighbors.add(newNode.getAddress());
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
||||
public SocketAddress getAddress() {
|
||||
try {
|
||||
return channel.getLocalAddress();
|
||||
} catch (IOException e) {
|
||||
LOGGER.severe("Address not set yet.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private byte[] addrToByte(SocketAddress addr) {
|
||||
// TODO Wäre cool, die IP nicht einfach als String zu schicken.
|
||||
// Was machen mit IPV4 vs IPV6?
|
||||
String s = addr.toString();
|
||||
return s.getBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Circularly link all neighbors, remove itself form all neighbors and exit.
|
||||
*/
|
||||
public void leave() {
|
||||
LOGGER.info("Name: " + getName() + ", Leaving...");
|
||||
|
||||
for (int i = 0; i < neighbors.size(); i++) {
|
||||
|
||||
if (neighbors.size() > 1) {
|
||||
buf.clear();
|
||||
buf.put(MessageType.NEW_NEIGHBOR_IPV6);
|
||||
if (i == 0) {
|
||||
|
||||
buf.put(addrToByte(neighbors.get(1)));
|
||||
buf.put(addrToByte(neighbors.get(neighbors.size() - 1)));
|
||||
|
||||
} else if (i == neighbors.size() - 1) {
|
||||
|
||||
buf.put(addrToByte(neighbors.get(0)));
|
||||
buf.put(addrToByte(neighbors.get(i - 1)));
|
||||
|
||||
} else {
|
||||
|
||||
buf.put(addrToByte(neighbors.get(i - 1)));
|
||||
buf.put(addrToByte(neighbors.get(i + 1)));
|
||||
}
|
||||
buf.flip();
|
||||
try {
|
||||
channel.send(buf, neighbors.get(i));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
this.neighbours.add(neighbour);
|
||||
}
|
||||
printInfos();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a list of new neighbours
|
||||
*
|
||||
* @param neighbours
|
||||
*/
|
||||
public void addMultiNeighbours(List<Node> neighbours) {
|
||||
Iterator<Node> it = neighbours.iterator();
|
||||
while (it.hasNext()) {
|
||||
addSingleNeighbour(it.next());
|
||||
}
|
||||
}
|
||||
buf.clear();
|
||||
buf.put(MessageType.LEAVE);
|
||||
buf.flip();
|
||||
|
||||
/**
|
||||
* Checks if actual node has neighbour with given id -> remove it
|
||||
*
|
||||
* @param node
|
||||
*/
|
||||
public void removeNeighbour(Node node) {
|
||||
for (int i = 0; i < this.neighbours.size(); i++) {
|
||||
Node tmp = this.neighbours.get(i);
|
||||
if (tmp.id == node.id) {
|
||||
this.neighbours.remove(i);
|
||||
try {
|
||||
channel.send(buf, neighbors.get(i));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
printInfos();
|
||||
}
|
||||
|
||||
public boolean hasNeighbours() {
|
||||
return (this.neighbours.size() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if actual node has neighbour with given id
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public boolean hasNeighbour(int id) {
|
||||
for (int i = 0; i < neighbours.size(); i++) {
|
||||
Node tmp = neighbours.get(i);
|
||||
if (tmp.id == id) {
|
||||
return true;
|
||||
try {
|
||||
if (thread != null) {
|
||||
udpListen.terminate();
|
||||
thread.join();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public List<Node> getNeighbours() {
|
||||
return this.neighbours;
|
||||
public boolean hasNeighbors() {
|
||||
return (this.neighbors.size() > 0);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Wenn die richtig implementiert ist, ist die
|
||||
* {@link #removeNeighbour(Node) removeNeighbour} ein Einzeiler.
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void printInfos() {
|
||||
StringBuilder result = new StringBuilder(128);
|
||||
result.append("Name: " + this.name + ", Neighbours: ");
|
||||
for (int i = 0; i < this.neighbours.size(); i++) {
|
||||
result.append(this.neighbours.get(i).name + ", ");
|
||||
|
||||
for (int i = 0; i < this.neighbors.size(); i++) {
|
||||
result.append(this.neighbors.get(i).toString() + ", ");
|
||||
}
|
||||
LOGGER.info(result.toString());
|
||||
}
|
||||
|
||||
}
|
||||
public class UDPListen implements Runnable {
|
||||
private volatile boolean running = true;
|
||||
|
||||
public void run() {
|
||||
while (running) {
|
||||
SocketAddress receivedFrom = null;
|
||||
buf.clear();
|
||||
|
||||
try {
|
||||
receivedFrom = channel.receive(buf);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
buf.flip();
|
||||
|
||||
byte messageType = buf.get();
|
||||
|
||||
switch (messageType) {
|
||||
case MessageType.INVITE:
|
||||
LOGGER.info(name + " received invite from "
|
||||
+ receivedFrom.toString());
|
||||
break;
|
||||
|
||||
case MessageType.LEAVE:
|
||||
|
||||
neighbors.remove(receivedFrom);
|
||||
|
||||
break;
|
||||
|
||||
case MessageType.NEW_NEIGHBOR_IPV4:
|
||||
LOGGER.info(name + " received new IPV4 neighbor"
|
||||
+ receivedFrom.toString() + ": "
|
||||
+ new String(buf.array()));
|
||||
|
||||
break;
|
||||
case MessageType.NEW_NEIGHBOR_IPV6:
|
||||
LOGGER.info(name + " received new IPV6 neighbor"
|
||||
+ receivedFrom.toString() + ": "
|
||||
+ new String(buf.array()));
|
||||
break;
|
||||
|
||||
default:
|
||||
LOGGER.info(name + " received unknown command from "
|
||||
+ receivedFrom.toString() + ": "
|
||||
+ new String(buf.array()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
package peer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class Peer {
|
||||
|
||||
private final static Logger LOGGER = Logger.getLogger(Node.class.getName());
|
||||
|
||||
private Node node;
|
||||
|
||||
public Peer(String name) {
|
||||
this.node = new Node(new Random().nextInt(), name);
|
||||
}
|
||||
|
||||
public Node getNode() {
|
||||
return this.node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create another peer, mutually link creator and spawn.
|
||||
*/
|
||||
public void spawn(String name) {
|
||||
LOGGER.info("Name: " + node.getName() + ", Spawning " + name);
|
||||
|
||||
// create a new node
|
||||
Node spawnNode = new Node(new Random().nextInt(), name);
|
||||
spawnNode.addSingleNeighbour(this.node);
|
||||
|
||||
// link new node to actual node
|
||||
this.node.addSingleNeighbour(spawnNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Circularly link all neighbours, remove itself form all neighbours and
|
||||
* exit.
|
||||
*/
|
||||
public void leave() {
|
||||
LOGGER.info("Name: " + node.getName() + ", Leaving...");
|
||||
|
||||
List<Node> neighbours = this.node.getNeighbours();
|
||||
|
||||
for (int i = 0; i < neighbours.size(); i++) {
|
||||
// add all neighbours
|
||||
neighbours.get(i).addMultiNeighbours(neighbours);
|
||||
// remove itself
|
||||
neighbours.get(i).removeNeighbour(this.node);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
package peer;
|
||||
|
||||
public class UDPListen extends Thread {
|
||||
|
||||
public UDPListen(int port) {
|
||||
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user